Сохранен 727
https://2ch.hk/pr/res/468317.html
Прошлые домены не функционирует! Используйте адрес ARHIVACH.VC.
24 декабря 2023 г. Архивач восстановлен после серьёзной аварии. К сожалению, значительная часть сохранённых изображений и видео была потеряна. Подробности случившегося. Мы призываем всех неравнодушных помочь нам с восстановлением утраченного контента!

Клуб изучающих PHP #49 да уже 49

 ОП 24/04/15 Птн 18:22:09 #1 №468317 
14298889290680.png
14298889290691.jpg
14298889290732.png
14298889290773.png
Добро пожаловать. В этом треде мы изучаем язык PHP (а также JS/CSS/HTML/SQL), решаем задачки и даже делаем простые сайты! Зачем? Кто-то хочет научиться программировать, кто-то - делать сайты, кто-то - просто размять мозги и заняться чем-то полезным.

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

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

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

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

У нас есть уроки по основам 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) когда тебе не надо тратить время на поиск заказов и переговоры с неадекватными заказчиками.
ОП 24/04/15 Птн 18:27:31 #2 №468322 
14298892512940.png
14298892512961.jpg
14298892513022.jpg
Код важно писать не как попало, а аккуратно и по правилам. Почему? Потому, что на неакуратно написанный код не хочется даже смотреть.

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

Аноним 24/04/15 Птн 18:36:08 #3 №468327 
Ну наконец-то.
Аноним 24/04/15 Птн 19:39:34 #4 №468386 
14298935748250.png
>>468294
>Дублируется. У тебя есть поле author в Article и есть поле name в Author.
Так оно же не в базе данных хранится, а формируется только при срабатывании этого специфического запроса. Ну и как сказать... это не 'поле author в Article' это совокупность полей из Article и Author и Subject.
>И почему в Article хранится только огрызок от автора, а не объект Author целиком?
Потому что мне для отображения статьи достаточно имени автора. Понадобится еще что-то - допишу в запрос. С другой стороны зачем брать Author-а целиком если нужно только имя?
>Ну и если у тебя есть класс Author то как получить Author из Article? Например как узнать дату регистрации автора статьи? Его id? Ссылку на его страницу?
Дописать нужные поля в запрос. Повторю картинку. Я тут не только имя автора взял, но и его биографию, также можно было взять айди и сформировать ссылку. То есть это я заморочился для наглядности с перечислением полей, можно просто SELECT * ... и туда попадет все на свете.
Аноним 24/04/15 Птн 19:52:07 #5 №468399 
А, погоди. Ты наверное имеешь ввиду что в зависимости от ситуации может понадобиться как одно имя автора, так и все поля целиком. А у меня получается не универсально. А если в $article->author класть объект, то можно еще и методами пользоваться. Хм.
Аноним 24/04/15 Птн 22:06:51 #6 №468451 
ОП, чекни задачку про банкомат. Вроде работает, но мне кажется, что код как-то оптимизировать можно. Не нравится, что по сути пришлось два почти одинаковых цикла создавать.

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

http://ideone.com/PvTHpo
Аноним 25/04/15 Суб 05:03:50 #7 №468537 
Бамп
Аноним 25/04/15 Суб 08:22:21 #8 №468562 
http://ideone.com/lGtOYa

Задачка на вертикальный текст.
Аноним 25/04/15 Суб 10:19:28 #9 №468577 
Аноним 25/04/15 Суб 10:20:09 #10 №468578 
>>468451
а сейчас что, нельзя что ли?
$amount = 6600;
Аноним 25/04/15 Суб 10:35:34 #11 №468586 
>>468578

Можно, но там есть дополнительное условие в задаче с заменой количества банкнот и добавлением новых. И при новых условиях выдать 6600 не получается, т.к. я не знаю как сделать проверку на сумму всех оставшихся в банкомате денег.
Аноним 25/04/15 Суб 12:15:28 #12 №468607 
решил задачу про кошек-мышек:
https://ideone.com/HTVZcS
Заранее спасибо, за конструктивные советы, ОП!
Аноним 25/04/15 Суб 12:25:24 #13 №468610 
>>468607
привет, ты давно пхп учишь? какие материалы изучал?
благодарю
Аноним 25/04/15 Суб 12:27:20 #14 №468611 
>>468610
Мне мама запрещает говорить с незнакомцами.
Аноним 25/04/15 Суб 12:31:10 #15 №468612 
>>468611
ок, я скажу твоей маме чтобы она разрешала тебе разговаривать с незнакомцами.

хотя ты уже заговорил.
Аноним 25/04/15 Суб 12:32:03 #16 №468614 
>>468612
Все, в игнор, дядя.
Аноним 25/04/15 Суб 12:35:36 #17 №468616 
>>468614
ты как с отцом разговариваешь, щщщщщщщеенок блядский, блять!
Аноним 25/04/15 Суб 12:39:14 #18 №468617 
>>468616
Не ври, мой отец работает на мкс. Скоро я наконец-то впервые увижу его, расскажу ему о твоих выходках.
Аноним 25/04/15 Суб 13:05:00 #19 №468623 
>>468610
до этого питонил года 1,5 наверное, где-то с конца осени прошлого года взялся за пхп.
Аноним 25/04/15 Суб 14:34:52 #20 №468653 
>>468623
И насколько сильно питон помог тебе в освоении пхп?
Аноним 25/04/15 Суб 16:41:59 #21 №468717 
>>468653
После django пришло стойкое осознания, как должена работать mvc.

Другой анон

Забежал на минутку. Я тут зависал зимой, решал задачки уже с базой данных студентов, но забросил. Сначала выучил django, а потом Java и Spring и занялся поиском работы. Работу я нашел на php, а значит я опять к вам. Сейчас делаю тестовое задания.
Аноним 25/04/15 Суб 16:54:22 #22 №468727 
>>468717
какие материалы можешь посоветовать по пхп?
чтобы годнота из годноты.
Аноним 25/04/15 Суб 17:06:14 #23 №468734 
>>468727
Документацию, наверно.
Аноним 25/04/15 Суб 18:00:25 #24 №468755 
Если скидываешь пустую форму то POST будет пустым?
Аноним 25/04/15 Суб 18:26:27 #25 №468769 
>>468734
но там же нипанятна написанааа!
вобше понятно, но не все
Аноним 25/04/15 Суб 18:32:46 #26 №468771 
>>468769
Зато ты не прочтешь устаревших вещей, это раз, во вторых, разбирайся, не все понимаешь с первого раза и бывает нужно несколько раз перечитать. Все, как и везде.

Вообще, в идеале учить все без привязки к конкретному языку, тогда и будет все годно.
Аноним 25/04/15 Суб 19:57:04 #27 №468796 
>Чтобы делать эти задания, тебе надо установить Апач + PHP
Вы че бля, какой нахуй апач? Нгинкс онли
Аноним 25/04/15 Суб 19:59:57 #28 №468800 
>>468653
ну изучение 2-го ЯПа легче дается. Помимо того, что изучаешь какой-то конкретный ЯП, касаешься и других областей, так или иначе, общих для программирования в целом.
Аноним 25/04/15 Суб 20:56:01 #29 №468809 
Почему регулярка не хочет искать слова "а" и "но"?

> !^(а|но)$!u

https://ideone.com/K7CG8Q
Аноним 25/04/15 Суб 20:58:42 #30 №468811 
>>468809

Потому что стоят ^ и $.
Аноним 25/04/15 Суб 21:02:35 #31 №468813 
>>468796
э бля сука уебок ламп ставь далбаеб хуев
Аноним 25/04/15 Суб 22:44:54 #32 №468824 
>>468796

Возни с настройкой нгинкс + fpm много, выгоды для 1 пользователя нет. на практике часто нгинкс ставят не вместо а перед Апачом.

Это обучающий тред. Вместо того чтобы давать бессмысленные советы, надо давать объяснения и ссылки на статьи. Если ты больше 2 слов в стиле «только хардкор» сказать ничего не можешь то лучше промолчать.

>>468813

Не ругайся в нашем треде.
Аноним 26/04/15 Вск 00:31:06 #33 №468856 
Скажите, если у меня есть например в базе таблица юзеров, и таблица коментариев.
В юзерах: id, username;
В комментариях user_id, user_post;
То я обязан их связать жестко на уровне базы?
Аноним 26/04/15 Вск 00:44:00 #34 №468864 
>>468856

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

Аноним 26/04/15 Вск 00:50:04 #35 №468865 
>>468864
А если я удалю из базы какого-то юзера? Удаляться и все комментарии которые связаны с его id? или mysql просто не даст мне это сделать? Пока все комментарии не будут удалены?
sageАноним 26/04/15 Вск 01:05:13 #36 №468873 
>>468865
man myisam
man innodb
ОП 26/04/15 Вск 01:24:18 #37 №468880 
Прочел что на Go сделали движок простого блога ( https://news.ycombinator.com/item?id=9439041https://kabukky.github.io/journey/ ) и разумеется не смог удержаться от того чтобы посмотреть.

Я не знаком особо с го, просто читал статью на Хабре и знаю что его делают в гугле (конкурент для раста? почему они не хотят его развивать?) и что в нем нет: классов, ООП, исключений.

Движок использует Sqlite и по стилю написания кода напоминает велоcипед на PHP из дофреймворковой эпохи, когда каждый писал как хотел. Никаких MVC там нет, код живописно раскидан по разным папкам в виде функций.

Go довольно похож на PHP так что вы, аноны, тоже можете глянуть. Помните только что точка тут значит не склеивание строк, а обозначает либо неймспейс (то есть templates.Update() равносильно templates\Update() в PHP) либо обращение к полю (post.id значит $post->id в PHP).

Вот их набор плагинов к шаблонизатору, где мы видим неудобный способ работы со строками: https://github.com/kabukky/journey/blob/master/templates/handlebars.go

Магические числа:

https://github.com/kabukky/journey/blob/master/templates/handlebars.go#L259
> if values.CurrentTemplate == 1 { // post
> } else if values.CurrentTemplate == 0 { // index
> } else if values.CurrentTemplate == 3 { // author

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

Так как нет исключений, код наполовину состоит из конструкций

if err != nil
return err

шаблонизатор — велосипедный handlebars c ужасным синтаксисом ( https://github.com/kabukky/promenade/blob/master/index.hbs ). Тот кто его делал никогда не видел нормальных шаблонизаторов (twig/jinja) и изобрел какой-то жуткий велосипед.

Работа с SQL напоминает PDO с примитивным data mapper: https://github.com/kabukky/journey/blob/master/database/retrieval.go

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

Справедливости ради, го наверно не для этого делался, но все равно, это показательный пример, кругом полно неучей и черное в их глазах перепутано с белым, а лучшее с худшим. Почему-то простой сайт на php на главной hacker news не висит.
Аноним 26/04/15 Вск 01:26:55 #38 №468882 
>>468865

Ты определяешь это когда задаешь внешний ключ, советую прочесть эту статью: http://denis.in.ua/foreign-keys-in-mysql.htm

>>468873

$ man innodb
No manual entry for innodb

Уходи, в век интернета и HTMl ты вместо понятной полезной ссылки на русском даешь неработабщую команду. Интересно, почему посты с сажей почти всегда пишут такие как ты неучи? Там же написано «мудрец» перед галочкой, а не «неуч».
Аноним 26/04/15 Вск 01:30:29 #39 №468883 
>>468880

И конечно же главный признак неуча-велосипедиста — ангулар — там присуствует также. надо следовать за модой!
Аноним 26/04/15 Вск 01:41:54 #40 №468887 
>>468883

Нашел оправдание от авторов (или пиарщиков?) го про обработку ошибок: http://blog.golang.org/errors-are-values

Этот подход с написанием дополнительных функций is ugly as a fuck. Мы это проходили 30 лет назад, зачем к нему возвращаться?

Мир дали им ООП и исключения, нет хотим быть не такими как все.
Аноним 26/04/15 Вск 02:06:56 #41 №468894 
>>468880
Даже ноде.жс выглядит конфеткой по сравнению с этим говном.
Аноним 26/04/15 Вск 06:04:47 #42 №468913 
>>468809
Переделал, теперь работает https://ideone.com/UOY6kk
Аноним 26/04/15 Вск 07:11:33 #43 №468917 
>>468913
Вот еще опечаточник https://ideone.com/f5V9HL Перемудрил?
Аноним 26/04/15 Вск 07:45:04 #44 №468921 
>>468386

Ты можешь скрыть реаизацию за счет метода. То есть сделать метод getAuthorName() у Article, а уже в нем писать либо

return $this->authroName;

либо

return $this->author->name;

И таким образом можно менять реализацию не трогая остальной код.

>>468399

Вот-вот.

>>468451

> И да, как сделать, чтобы 6600 можно было выдать
Это задача о ранце:

http://informatics.mccme.ru/mod/book/view.php?id=815
http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BE_%D1%80%D1%8E%D0%BA%D0%B7%D0%B0%D0%BA%D0%B5

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

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

перебратьКупюры(требуемаяСумма, набраннаяСумма, оставшиеся купюры) {

берем старшую из оставшихся купюр;
(меняем число этих купюр от максимального имеющегося до 0) {
если сумма набралась то ответ найден;
иначе вызываем функцию перебора купюр, передавая ей оставшиеся купюры (без старшей);
}
}

При каждом рекрсивном вызове передается набор купюр без самой старшей, так что за 5-6 вызовов мы дойдем до самой младшей. Этот код перебирает все возможные комбинации купюр.

Кстати тут можно использовать такую фичу php как генераторы: делаем чтобы функция перебора работала как генератор всех возможных комбинаций купюр и пишем:

foreach (generateCombinatons(..) as $combination) {
если комбинация купюр дает нужную сумму, выводим ее;
}

Аноним 26/04/15 Вск 07:50:11 #45 №468922 
>>468451

>$numberOfBills = floor($totalAmount / $bill);
> if ($numberOfBills > $number) {
Это короче записать без ифа, через max/min

> $i++;
> if ($i == $billsCount && $totalAmount > 0) {
Эту проверку можно поставить после цикла и тогда переменная i не нужна

2 цикла для такой простой программы слишком много, к тому же ты их скопипастил а копипаста страшное зло. Убери второй цикл и копипасту. Можно например в массив запоминать число купюр.
Аноним 26/04/15 Вск 08:07:02 #46 №468924 
>>468562

> foreach ($textStrings as $string) {
> $stringLength = mb_strlen($string);
> if ($stringLength > $maxLength) {
С помощью функции array_map этот цикл можно заменить на одну строчку. Догадайся, как.

В остальном верно.

>>468578

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

>>468607

> private $fieldSchema;
думаю нет никакого смысла хранить его как поле так как оно устаревает и пересоздается каждый ход. Думаю логичнее сделать его переменной.В полях лучше хранить более постоянные вещи.

> if(get_class($animal) === "Mouse") {
Это не очень ООП, так как добавление новых видов животных потребует правки кода тут. А надо чтобы их можно было добавлять без этого. Думаю логичнее у животного сделать метод возвращающий его обозначение.

> $chunkedField = array_chunk($this->fieldSchema, $this->fieldSize, true);
> $fieldSchemaLined = array_merge($fieldSchemaLined, $chunk);
Проще по моему сделать двухмерный массив вместо этих сложных преобразований которые тяжело читать и проверять.

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

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

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

Например метод private function findVisibleField($sideSize) — чтобы его понять, надо сидеть и с листочком выписывать и проверять все эти формулы. Боюсь, это неприемлемо, я хочу чтобы там был наглядный и очевидный код. В случае с x/y будет примерно такое:

$leftBound = max(0, $x - $radius);

что в разы проще, по моему.


> abstract class Animal
> public function __construct($fieldSize)
Непонятно зачем животному передавать размер поля.

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

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

> class Game
> private $fieldSize;
> private $animals = [];
Эти поля дублируют поля в карте и думаю их лучше удалить. Дублирующиеся данные это всегда плохо, источник истины должен быть один.




Аноним 26/04/15 Вск 08:20:06 #47 №468925 
>>468755

Поставь var_dump($_POST); в скрипт и проверь.

>>468913

Хорошо, но хорошо бы еще показывать где пропущена запятая или пробел.

Также программа вставляет лишние запятые: https://ideone.com/Kb10ml

> \s(но|а)\s
Это не сработает если за словом идет запятая. Луче использовать \b

>>468917

> $patterns = array(
> $replacements = array(
Неудобно что буква и ее пара далеко друг от друга. Лучше сделать так

array(
'a' => 'a',
...

Заменять буквы можно и без регулярок, тут strtr хватит, она была в задаче про шифровку.

У тебя программа реагирует на все ангглийские буквы. Но надо искать только слова со смешанными алфавитами и в английских словах выделят русскую букву, а не как тут: https://ideone.com/awHmfP



Аноним 26/04/15 Вск 11:04:01 #48 №468943 
>>468880
надо было еще к this_is_my_variable вернуться для порядка.
Аноним 26/04/15 Вск 13:18:58 #49 №468968 
14300435387790.jpg
>>468317
Чего стоит ожидать от сервера за 12$ в год?
Аноним 26/04/15 Вск 13:49:55 #50 №468978 
>>468968
Error 503 - Service unavailable
Аноним 26/04/15 Вск 14:11:32 #51 №468995 
>>468978
А какой брать? Как оценивать нагрузку?
Воннаби 26/04/15 Вск 15:19:07 #52 №469020 
14300507475780.png
Недо-джун устроившийся на пол ставки за еду слегка рапортует.

Отработал в общем первую неделю. Меня посадил начальник пилить собственную небольшую хэлп-деск систему на кодигнайтере. Вроде бы успешно справляюсь, хоть и с помощью и подсказками, но начинаю понимать во всем этом. Пока что допиливаю админку. Сначала удивило то, что к любому методу, свойству или еще чему, можно обращаться через $this->user->add_user() например, хотя метод add_user() описан в моделе, а ты сидишь ковыряешь контроллеры. Как будто ты находишься в 1 глобальном объекте все время, и внутри него обращаешься к его же методам и свойствам. Везде такой подход используется в mvc - фреймворках?

Далее, ОП, я так и не смог разобраться с примером на написание микро шаблонизатора через анонимные функции и preg_replace_callback, но я обязательно вернусь к этому, не собираюсь бросать так сказать учебу, тем более что у меня работа пока всего по 4 часа в день.
Спасибо за ссылку >>468882 как раз возникли проблемы с базой. В общем там сделано так, что в базе просто лежат таблицы пользователей, сайтов, задач и событий. Они не связаны никак. И похоже что их уже нельзя связать. Ведь они заполнены. Либо придется вычищать все с базы, переделывать таблички, и после этого снова заполнять. Во всяком случае в phpmyadmin почему-то нет строчки со связями. Вот прикручиваю для примера скрин своей локальной поделки, и тут у меня все есть. Может быть конечно там другая версия phpmyadmin, но все же мне не ясно пока как это сделать.
Аноним 26/04/15 Вск 19:53:38 #53 №469131 
http://ideone.com/M5fIre
Аноним 26/04/15 Вск 19:57:26 #54 №469135 
Есть тут Yii2-боги?
Аноним 26/04/15 Вск 19:58:58 #55 №469136 
>>469131
http://ideone.com/mMY4hr
И сразу эррор без внесения каких-либо правок в твой код.
Аноним 26/04/15 Вск 20:05:09 #56 №469139 
Кстати, поясните про фреймворки. Я когда HTML учил, то ковырялся в некоем бутстрапе, но уже ничего не помню о нем если честно.

Насколько я понял фреймворки это что-то типа шаблонов с готовыми решениями для создания однотипных сайтов? Долго ли их изучать и сложно ли дается это изучение? В чем между ними принципиальная разница?
Аноним 26/04/15 Вск 20:07:10 #57 №469141 
Почему не видит переменные, что вне функции?http://ideone.com/ze5reJ

Задачка про iPad.
Аноним 26/04/15 Вск 20:09:33 #58 №469142 
>>469141
>startprice
>startPrice
Аноним 26/04/15 Вск 20:10:51 #59 №469144 
>>469141

Потому что все что происходит в вегасефункции, остается в функции.

Алсо,

>persent
Аноним 26/04/15 Вск 20:13:12 #60 №469146 
14300683921320.jpg
>>468995
Ну ответьте, знающие люди.
Аноним 26/04/15 Вск 20:13:44 #61 №469147 
>>469141
Внутри функции пропиши:

global $varName;

Для нужных глобальных переменных.
Аноним 26/04/15 Вск 20:23:53 #62 №469155 
>>469131
http://ideone.com/1ovDIH
sageАноним 26/04/15 Вск 20:28:25 #63 №469159 
>>468995
digitalocean
sageАноним 26/04/15 Вск 20:28:50 #64 №469160 
ну чо есть какие новые задачи или всё кошей/мышей гоняете третий год?
Аноним 26/04/15 Вск 20:39:01 #65 №469166 
>>469139
Фреймворки это готовый код. Берешь и с их помощью пишешь в 2 строчки то, что в ручную заняло бы 20. Например вместо всякой еботни с базой, ты просто берешь и пишешь $this->db->update($table, $data);
И вот эта строчка за тебя установит соединение с базой, проверит валидность там, и все такое, потом внесет инфу туда и завершит соединение. Функция update - не входит в состав php, а является частью фреймворка. В общем это некая эволюция библиотек, когда разработчики писали свои функции, кидали их в отдельный файлик, который был этой самой библиотекой, а потом инклудили его в своих целях куда хотели.

Бутстрап это html - фреймворк, который упрощает работу с html, в нем сразу за тебя написаны все заготовки и вместо ебли с html\css, ты можешь просто прописать своей кнопке class="btn-danger" и у тебя будет готовая красная кнопка. Отлично взлетает вместо стандартного голого уродливого html.

>Насколько я понял фреймворки это что-то типа шаблонов с готовыми решениями для создания однотипных сайтов?

Это ты про CMS - Системы управления контентом. Вот они как раз позволяют быстро клепать однотипные сайты наверное даже без знания программирования. Ты просто ставишь эту CMS как движок, и используя её возможности делаешь свой бложик или галерею, ну и как-то так.

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

>В чем между ними принципиальная разница?
На этот вопрос я тебе ответить не могу. Думаю гугл поможет

Вот что говорят про твои вопросы в целом
https://toster.ru/q/15011
http://habrahabr.ru/post/50341/
Аноним 26/04/15 Вск 20:39:45 #66 №469167 
>>469160
Я даж до мышей не дошел еще, на векторе завис.
Аноним 26/04/15 Вск 20:55:29 #67 №469179 
>>469166

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

Цель у меня на работу устроиться джуниором. Просто слышал, что мол особо глубоких знаний php не требуют, т.к. все равно все на фреймворках пишут. Уровень знаний слабенький, дошел до ООП и встал, чет тяжело дается. Вроде бы принцип понял, но чет какой-то огромный скачек между первым/вторым заданием и остальными про кошек мышек и превьюшку. Теряюсь сразу же, даже не знаю с чего начать.
sageАноним 26/04/15 Вск 21:18:17 #68 №469193 
>>469167
геометрия?
Аноним 26/04/15 Вск 22:04:02 #69 №469216 
>>469179
У меня тоже были проблемы с этим. Долго рос и ковырялся неделями в одной задаче, больше конечно из-за лени или типа того.

Если хочешь можешь глянуть мой код по вектору. Он с косяками в плане архитектуры, но задачу решает на ура. Можешь попробовать от него оттолкнуться когда будешь сам решать
http://ideone.com/jKnvgR
Аноним 26/04/15 Вск 22:11:22 #70 №469222 
Я могу сделать сайт с регистрацией и авторизацией на хтмл+пхп+МАЙСОКЛ, но не осилил задачу с банкоматом(другие не смотрел). Я совсем безнадежен?
Аноним 26/04/15 Вск 22:13:12 #71 №469225 
>>469222
нет, просто у тебя больше знаний в технологиях, чем в алгоритмах.
Аноним 26/04/15 Вск 22:14:34 #72 №469227 
>>469225
Посоветуешь какую нибудь литературу\статьи по алгоритмам?
Аноним 26/04/15 Вск 22:19:39 #73 №469232 
>>469227
Нет, я такой же как ты. На википедии все эти алгоритмы описаны по сути. Я так и не решил её хитрым алгоритмом, а решал просто жадным.

Выдаем купюры 5000 пока остаток больше 1000, далее начинаем выдавать 1000 пока остаток больше 1000, потом выдаем 100 пока больше 100 и далее выдаем мелоч. Вроде бы как-то так было.
sageАноним 26/04/15 Вск 22:26:06 #74 №469235 
киньте ссылку на вектор пж
Аноним 26/04/15 Вск 22:32:59 #75 №469242 
>>469235
http://archive-ipq-co.narod.ru/l1/pasta.html
sageАноним 26/04/15 Вск 22:46:00 #76 №469247 
>>469242
внизу да?
порешаю чо, спс
Аноним 26/04/15 Вск 23:07:09 #77 №469257 
>>469222
МАЙСИКЛ

Так правильнее.
Аноним 26/04/15 Вск 23:23:58 #78 №469263 
>>469257
Ай вонт ту райд ма майсикл!
Аноним 27/04/15 Пнд 02:10:21 #79 №469308 
https://ideone.com/AuudWD
Аноним 27/04/15 Пнд 06:01:46 #80 №469314 
>>469193
ООП без математики.
Аноним 27/04/15 Пнд 13:03:19 #81 №469424 
>>468317
Поскольку кусок кода маленький кину сюда
<div name="test">
<p>
Комментарий:<Br>
<textarea value="16" class="text" name="comment" cols="110" rows="4"></textarea>
</p>
<input style="margin-left: 50px; " type="checkbox" name="anonymous" >Анонимно
<button class="send">Отправить</button>
</div>

Как получить значение textarea после клика по .send?Если делаю по клику на саму textarea то через $(this).val() я его получаю, а как получить по клику на сенд чето не могу догнать. пробовал уже и prev(естественно, меняя порядок) и closest() и по селекторам. не могу :( помогите, пожалуйста
Аноним 27/04/15 Пнд 13:20:47 #82 №469426 
>>469424
сделал так, но чую это костыльное решение:
$(".send").click(function(){
var text = $(this).parent().find(".text").val();
});
Аноним 27/04/15 Пнд 14:19:10 #83 №469443 
>>469424
Лучше всего дать им id. Будет
<textarea id="comment" ...></textarea>
<button class="send" id="submit">Отправить</button>
<script>
$(document).ready(function() {
$("#submit").click(function(){
alert($("#comment").val());
});
})
</script>
Аноним 27/04/15 Пнд 14:32:00 #84 №469449 
>>469443
>>469426
>>469424

Вам всем надо идти изучать CSS селекторы и яваскрипт/DOM прежде чем изучать jQuery. Элемент формы во-первых легко ищется по имени, то есть [name=x], во-вторых по имени через DOM: form.elements.name

Форму легко найти через this.form в обработчике или через closest.

> $(this).parent().find(".text").val( );
Такое вообще писать неправильно. Стоит добавить один див например и это перестанет работать.

Аноним 27/04/15 Пнд 17:12:54 #85 №469533 
Я тут узнал только что, что оказывается в php рисовать можно. Вот только вопрос, нахуя? Это же пиздец гемморно.
Аноним 27/04/15 Пнд 18:00:07 #86 №469558 
>>469533

А, все, вопрос отпадает.
Аноним 27/04/15 Пнд 18:00:28 #87 №469560 
14301468286510.jpg
>>469533
Можно запилить свою капчу, я таким страдал.
Аноним 27/04/15 Пнд 18:06:39 #88 №469562 
>>469560

Да я уже понял. Вся суть в том, что картинки можно делать динамичными и они будут меняться в зависимости от каких-либо условий. Ту же капчу думаю не сложно сделать, просто на каждый параметр по массиву создаешь с вариантами и через array_rand выводишь случайное значение.
Аноним 27/04/15 Пнд 18:09:47 #89 №469565 
>>469562
Ну не тока капчи, вотермарки можно ставить, можно обрезать картинки которые пользователь грузит на сервер, менять размер по всякому, можно написать какой-нибудь ебовый фильтр распознающий голых баб и автоматом стучащий в роскомнадзор и продать государству, применений миллион.
Аноним 27/04/15 Пнд 18:16:56 #90 №469571 
>>469565

Круто, на самом деле. Просто я изначально начал смотреть видос на эту тему и там чувак ничего про это не рассказал, а просто какие-то кружочки рисовал и прочую фигню, вот я и подумал, мол нафиг этот недопейнт нужен.

Вообще, так и не нашел ни один нормальный курс видеоуроков. Везде какие-то косноязычные уебаны, которые про всякую хуйню рассказывают вместо полезной информации.
Аноним 27/04/15 Пнд 18:23:57 #91 №469576 
>>469571
Не хочу за все говорить но на русском обычно курсы ведут чуваки типа Евгения Попова, более продвинутые ребята перекатываются в англоязычные комьюнити, поэтому так оно и есть.
Аноним 27/04/15 Пнд 18:27:57 #92 №469580 
>>469576

Ну я английский вроде более-менее знаю, но изучать на нем языки программирования для меня слишком тяжко. Так что приходится довольствоваться тем, что есть. В любом случае, для меня главное суть понять и начать что-то делать, а в случае любых непоняток есть гугл.
Аноним 27/04/15 Пнд 21:11:48 #93 №469708 
ОП пропал и тред затух? Кому подсказать может быть что-то?
Аноним 27/04/15 Пнд 21:30:23 #94 №469717 
>>469708
Книжечку подскажите, чтобы почитать на досуге новичку.
Аноним 27/04/15 Пнд 22:04:25 #95 №469744 
>>469717
уроки опа почитай. Я когда брался книжечки читать, не мог пробиться через предварительную воду в виде всяких настроек WAMP стеков и прочего описания как работает веб в первый день, а раз в первый день нихуя не сделано практического, то и интерес падал. Или ты не полный нуб? тогда php 5 в подлиннике читни.
Аноним 27/04/15 Пнд 22:05:20 #96 №469747 
>>469020

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

Странные вещи ты пишешь. $this->user->add_user() это вызов метода add_user() у объекта который хранится в $this->user, почему это контроллер? Контроллер это если бы ты писал $this->add_user(). А так в $this->user может быть любой другой объект (модель в данном случае). Ты точно уроки по ООП проходил?

Логичнее было бы спросить почему мы пишем $this->user-> ... а не $user = new UserModel( ); $user->...

Потому что в кодеигнитере загрузка и подключение разных компонентов сделаны именно таким образом, что ты пишешь например $this->load->model('x') и он загружает модель в $this->x. Тут можно задать еще один вопрос, а откуда загрузчик $this->load знает в какой контроллер надо добавить поле x? Ну это просто, он добавляет поле x не в контроллер, а в базровый класс CI_Controller, а все наши контроллеры от него унаследованы.

Так что посмотри выше, там где-то стоит $this->load

Кстати, так как основной класс фреймворка это CI_controller и он используется только для наследования и сам по себе не создается, то пока не создан контроллер, большинство методов фреймворка не работает, а get_instance() вернет null.

мануал: https://ellislab.com/codeigniter/user-guide/libraries/loader.html
https://ellislab.com/codeigniter/user-guide/general/controllers.html

Я советую тебе открыть исходники классов CI_Controller, Loader и посмотреть их самому. Кодеигнайтер небольшой по объему, простой и его легко изучать.

Вообще этогт класс Loader (изучи мануал и его код) это наследие времен PHP4 когда не было автозагрузчика и приходилось вот так вот вручную загружать нужные классы.

> Везде такой подход используется в mvc - фреймворках?
Везде по разному. Я думаю, этот вопрос пока что не имеет смысла так как ты не так понял код.

> И похоже что их уже нельзя связать. Ведь они заполнены
Неправда. Ты и SQL наверно не до конца изучил, если не знаешь что внешние ключи можно добавить на существующие таблицы командой ALTER TABLE ADD FOREIGN KEY: http://phpclub.ru/mysql/doc/alter-table.html

Проверить наличие ключей лучше не по отсутствию ссылки в phpmyadmin (это вообще ничего не говорит, кто его знает почему он ссылку не выводит) а сделав запрос SHOW CREATE TABLE x и посмотрев есть в описании таблицы ключи или нет (вообще. начинающим надо больше писать запросы руками и меньше пользоваться графическими инструментами; это инструменты для опытных программистов).

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

— проверить нет ли странных значение типа 0, -1
— проверить есть ли несуществующие id, это легко делается запросом с LEFT JOIN
— также, для создания внешнего ключа, типы колонок должны совпадать полностью. включая число в скобочках у INT(10)

Соответсвенно, надо проверить, нет ли расхождений, если есть то написать скрипт/SQL команду их исправления, и добавить ключи.

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

Вообще, все изменения надо на тестовой базе сначала делать.

По мне так это делать минут 30, ну у тебя как у начинающего может несколько часов займет.

Ну и надо читать больше документации и смотреть код кодеигнитер. Без этого ты в нем разбираться не будешь.
Аноним 27/04/15 Пнд 22:19:55 #97 №469765 
>>469744
Спасибо.
Аноним 27/04/15 Пнд 22:20:02 #98 №469766 
>>469131

> PHP Notice: Undefined offset: 4 in /home/PSNgOx/prog.php on line 21
Ты берешь число от 0 до count(..) но в массиве нет элемента с номером count(..), так как если в массиве 4 элемента то они имеют индексы 0, 1, 2, 3, а индекса 4 нету.

>>469136

То же самое

>>469139

Фреймворк позволяет грамотному верстальщику не тратить время на верстку набора элементов (меню, кнопки), а взять и использовать готовые (которые предоставляет фреймворк).

Фреймворк не освобождает от необходимости знать HTML/CSS на хорошем уровне. Без этих знаний ты будешь либо делать некачсетвенную верстку либо тратить кучу времени на исправление простых ошибок, кастомизацию, на какие-то нестандартные вещи (которые требуются почти в каждом проекте).

Так что сначала убедись что у тебя есть знания этого самого CSS. Если ты в них не уверен, у нас есть задания (в первом посте) которые помогают выявить и исправить пробелы в знаниях.

>>469141

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

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

>>469146

Как мы тебе ответим если мы не пользовались этим провайдером? Пока шишки не набьешь, не узнаешь. VPS за 60 или 120 долларов в год может оказаться ровно такого же качества.

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

>>469147

Нет. Это глупый и неправильный подход который запутаывает код. Данные надо передавать через аргументы.

>>469155

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

>>469160

Первый пост треда с задачами. Ну и для тебя вот есть отдельные: https://github.com/codedokode/pasta/blob/master/interview-tasks.md

Аноним 27/04/15 Пнд 22:27:58 #99 №469776 
>>469179

> особо глубоких знаний php не требуют, т.к. все равно все на фреймворках пишут
Ты не можешь пользоваться фреймворками без отличного знания PHP и тем более ООП. Это как пытаться решать уравнения с синусами не зная 4 арифметических действий. Фреймворки не для того чтобы не надо было учить php, а для того чтобы не писать код повторно. но на них часто сложнее писать чем без них.

> Вроде бы принцип понял, но чет какой-то огромный скачек между первым/вторым заданием и остальными про кошек мышек и превьюшку.
А ООО вектор делал? Пости код, пусть даже недоделанный, напиши на чем завис и попроси подсказку.

>>469216

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

>>469222

Запости код, напиши на чем завис. Там алгоритм очень простой. Считаем сколько надо самых старших купюр, потом купюр поменьше и так до самых маленьких.

>>469225

Просто он видимо пропустил главы по PHP и из-за этого на реальных приложениях будет тупить и тратить время на простые проблемы.

>>469247

Для тебя (вообще, конечно я его всем даю) есть дополнительный пункт к этой задаче:

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

1. Сократить в каждом департаменте 40% (округляя в большую сторону) инженеров, преимущественно самого низкого ранга. Если инженер является боссом, вместо него надо уволить другого инженера, не босса.

2. Увеличить в целях стимуляции умственной деятельности базовую ставку аналитика с 800 до 1100 тугриков, а количество выпиваемого им кофе с 50 до 75 литров. В тех департаментах, где руководитель не является аналитиком, заменить его на аналитика самого высшего ранга из этого департамента (а бывшего руководителя вернуть к обычной работе)

3. В каждом департаменте повысить 50% (округляя в большую сторону) менеджеров 1-го и 2-го ранга на один ранг с целью расширить их полномочия.

Совет директоров в затруднении: какой путь выбрать? Помоги им с этим, распечатав прогноз по потреблению и расходам (аналогичный тому что требуется в задаче) после принятия каждой из мер.
Аноним 27/04/15 Пнд 22:31:50 #100 №469781 
>>469308

Неплохо, но вот пара улучшений:

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

> $length = mb_strlen($text1);
> $halfLength = floor($length / 2);
Это почему-то 2 раза скопировано.

> $text1
лучше оставить просто $text

Номера символов считаются странно:

> $f = mb_substr($text1, $i - 1, 1);
Тут получается -1, 0, 1, 2, ....

> $l = mb_substr($text1, -$i, 1);
Тут получается -0 = 0, -1, -2, -3 ...
Аноним 27/04/15 Пнд 22:35:30 #101 №469787 
>>469424

Найти форму через сlosest и найти в ней элемент по имени [name=...]

>>469533

Графики, схемы. Иероглифы можно картинкой рисовать для тех у кого шрифт не установлен.

>>469744

Часто книги требуют каких-то предварительных знаний (это обычно написано в начале или предисловии). Например знания HTML/CSS и работы с сервером.

Также, по PHP много устаревших и плохих книг.



Аноним 27/04/15 Пнд 22:53:34 #102 №469805 
14301644148110.png
>>469766

Я вообще-то про фрейморки на php речь вел. Bootstrap привел как пример того, с чем я имел дело. И насколько я помню там ничего сложного нет вообще и никаких суперзнаний не надо.

>>469776

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

Вот недомакет накидал дизайнер из меня хуевый, знаю. Все примитивно конечно, но для начала думаю сойдет. Постараюсь даже CMS запилить для предпросмотра вебмок, чтобы всякое говно не загружали.
sageАноним 27/04/15 Пнд 23:07:40 #103 №469812 
доделайте, мне лень
http://ideone.com/LXofT6
Воннаби 27/04/15 Пнд 23:20:53 #104 №469828 
14301660537870.jpg
>>469747
>Странные вещи ты пишешь.
Да, так и знал что ересь какую-нибудь напишу. Конечно же у меня еще туговато с ООП, и да, я просто лишь хотел сказать, что пишем не так как на голом пхп с созданием объекта через
$object = new Class;
с дальнейшим обращением к свойствам и методам этого юзера таким образом:
$object->method(); $object->property;

А просто описывается новый класс, но объект не создается, и ко всему подряд можно обращаемся через $this->class->method();
$this->class->property;

>$this->load->model('x')
Так не пишем.
пишется в конфигах
$autoload['model'] = array('user', 'post', 'site');
например, и так подключаются все классы для модели.
В общем вот содержимое файла autoload.php из папки configs текущей версии игнайтера. http://ideone.com/c5nBKk Бтв вышла месяц назад 3.0

>Вообще этогт класс Loader (изучи мануал и его код) это наследие времен PHP4 когда не было автозагрузчика и приходилось вот так вот вручную загружать нужные классы.
А что есть автозагрузчик? Там есть в конфигах файл автолоад, и в него просто прописываешь классы новые. Наверное ты все же про старые версии фреймворка мне говоришь.

>Неправда. Ты и SQL наверно не до конца изучил, если не знаешь что внешние ключи можно добавить на существующие таблицы командой ALTER TABLE ADD FOREIGN KEY: http://phpclub.ru/mysql/doc/alter-table.html

В общем дело было в следующем, у нас таблицы были сделаны на Myisam, а он не поддерживает ключи: http://rtfm.co.ua/mysql-otlichiya-mezhdu-myisam-i-innodb/
В итоге после того как конвертировал все таблички в innoDB, стало возможно связать их.

>Я советую делать это не на продакшене, а сделать отдельную тестовую БД и на ней тренироваться.
И так ковыряюсь в специально скопированном сайте, а "продакшен" пока без изменений, как начальник посмотрит что я там написал наверное отправит на допил, потом же перенесем.

>Ну и надо читать больше документации и смотреть код кодеигнитер. Без этого ты в нем разбираться не будешь.
Спасибо, стараюсь, стал куда больше читать и гуглить в последнее время, что бы во всем разобраться с чем сейчас работаю.
Аноним 27/04/15 Пнд 23:25:24 #105 №469836 
Как обзывать таблицы в базе данных которые хранят всякие причиндалы для сайта знакомств, типа Отношение к алкоголю и там негативно, умеренно, язвенник, бухаю с ночи, или материальное положение (богатый, нищий, ищу спонсора), семейное положение (женат, разведен, свободен). И сами колонки как можно назвать одним словом само 'отношение к бухлу'? У меня уже мозг закипает придумывать всякие охуительные названия.
Аноним 27/04/15 Пнд 23:32:56 #106 №469853 
>>469836
Всё неправильно.
Должна быть таблица "пользователь", таблица "вопрос" и сводная таблица "вопрос-пользователь" где две колонки: "user_id" и "question_id".
Аноним 27/04/15 Пнд 23:34:56 #107 №469858 
>>469836
Таблица:
user_info например

Поля:
alcohole_attitude:

financial_condition:

family_status:

Ну и делаешь там значения этих колонок со строгим выбром из: Женат / Замужем / Холост / Свободна / В поиске изи же?

Я тебе за 3 минуты накидал это с помощью https://slovari.yandex.ru/
Аноним 27/04/15 Пнд 23:46:44 #108 №469877 
>>469853
И что мне это даст как потом сделать запрос чтобы оно все в одну таблицу попало с колонками типа
ID пользователя, вопрос о курении, вопрос об алкоголе, вопрос о семье...
1, курит, не пьет, замужем

Аноним 27/04/15 Пнд 23:50:54 #109 №469890 
Эти вопросы же, точнее ответы на них будут намешаны в одной таблице если я правильно понял
ID пользователя, вопрос
1 курит
1 пьет
1 замужем
1 богат
2 не курит
2 не пьет
и так далее
Аноним 27/04/15 Пнд 23:57:21 #110 №469899 
>>469890
>>469853
>469853
При чем тут вообще вопросы? Это ведь инфа которую юзеры заполняют о себе по сути, и больше нихуя. Можно хоть в таблице самого юзера хранить вместе с паролем, мылом и хэшем для запоминания. А можно и в отдельной, чисто вынести всю информационную поеботу в неё, начиная от возраста и заканчивая сколько раз в день дрочишь. хз надо смотреть как будет работать это дело по скорости, ибо у меня опыта нету.
Аноним 28/04/15 Втр 00:12:20 #111 №469927 
14301691408630.jpg
>>469899
Ну дык всю эту ебаторию не только хранить абы как надо, а еще доставать, выводить, сортировать по ней. Выходит что в таблице самого юзера надо хранить вот это
>>469858
alcohole_views_id - 1
smoking_views - 2
family_status - 0
и в отдельных таблицах типа alcohole_views две колонки - айди и само "отношение"
1 - выпиваю
2 - не пью
3 - по праздникам
Так их хотя бы можно согнать в одну таблицу через вложенный запрос.
Ох и выбрал же я себе задачу, сижу охуеваю с этих быдлопроблем.
Аноним 28/04/15 Втр 00:26:14 #112 №469940 
>>469927
и зачем тебе отдельные микро таблицы тогда? Не проще ли сделать просто массивы соответствий? Ты либо храни все сразу в одной табличке, в том числе и значения "выпиваю" "замужем"
Либо если тебе хочется хранить какие-то циферки, то сделай сорт оф языковой файл, где будут зашиты массивы вида:
$user_smoking[1 => 'курю'];
$user_smoking[2 => 'не курю'];
$user_smoking[3 => 'дрочу на элетронные сиги и сру всем этим в уши, смотрите же!'];ъ

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

Потом даже можно в перспективе расширять сайт на второй язык, прикрутив например такой же файл, но с английским
$user_smoking[1 => 'курю'];
$user_smoking[2 => 'не курю'];

И подгружать его если пользователь выбрал языком интерфейса английский.
Аноним 28/04/15 Втр 00:27:39 #113 №469941 
>>469940
$user_smoking[1 => 'smoke'];
$user_smoking[2 => 'don't smoke'];
Аноним 28/04/15 Втр 00:37:05 #114 №469946 
>>469940
Ну я спрашивал за эту тему у авторитетов, мне дипломированные забугорные sql-синьоры сказали что за малейшее смешивание логики и данных сразу на парашу отправляют. Даже пол нельзя хранить в виде 1, 2, а в коде делать свич (секс) { '1': мужик, '2': баба} , все надо в отдельных таблицах.
Аноним 28/04/15 Втр 00:44:13 #115 №469951 
>>469946
ну это адепты учебников каких-нибудь. А теперь представь что вконтакте хранит всю инфу строго в базе, представь сколько там говна будет и какие длинные цепочки связей будут получаться. Инфа 100 для высоконагруженной хуйни используются подобные хитрые подходы.
Аноним 28/04/15 Втр 00:59:51 #116 №469963 
>>469946
и вообще у тебя не будет смешения логики и данных. У тебя будет логика так же ходить по приложению в том виде в котором она в базе лежит. То есть например выходит у тебя объект user
и у него поля
sex => 1
smoke => 3
suck_cock => 1

и где-то есть массив
$lang['sex'][0 => 'Пол', 1 => 'Мужской', 2=>'Женский', 3 => 'девочка внутри'];

А когда все приходит во вьюху или не знаю там, во фронтэнд, то эти значения подгружаются из массива соответствий

<p>Пол: <?= echo lang['sex'][user->sex] ?><p>
В общем как-то так. Хотя можно сделать что у тебя ни одной буквы русской там не будет:

<p><?= echo lang['sex'][0] ?>: <?= echo lang['sex'][user->sex] ?><p>


В общем я хуево объяснил, потому что я не могу подглядеть прямо сейчас в то, как там у меня на работке используется, но в принципе мне самому эта идея нравится. Имхо в базе надо хранить в текстовом виде только то, что не будет постоянно копипастой: всякие сообщения или емейлы там, а такое говно храни циферками в одной таблице и гоняй их куда хочешь, а как до вывода пользователю дело дошло, то подключай файл языка и выводи значения из него.
Аноним 28/04/15 Втр 03:12:24 #117 №469989 
14301799447900.jpg
Анончик, выполнил еще одну задачу. Вот принес, чтоб ты сказал, над чем мне работать: http://ideone.com/cB2teU
В этот раз старался поаккуратнее делать.

И пара вопросов:
1) Какой редактор кода для PHP имеет такую же хипстерскую подсветку синтаксиса, как и на Codeacademy? Или это можно накрутить в любом редакторе?
2) Где можно почитать об аккуратности оформления кода? Насколько для форматирования пригоден Phpformatter?
Аноним 28/04/15 Втр 07:59:28 #118 №470007 
>>469989
В сублиме техт и бракетс точка ио точно накатить няшную подсветку синтаксиса можно.
Аноним 28/04/15 Втр 08:37:24 #119 №470014 
>>468317
Привет, php. Вопрос следующего формата. Нужно написать на php одну фичу. я с php не работал, но придумал следующий дизайн: фронтенд рисую на штмл и js, а на php пишу только апи движок. Вопроса два: какие подводные камни у такого подхода и второй, что можно почитать/какой фрейморвк использовать для серверного php. Смотрю в сторону yii.
Аноним 28/04/15 Втр 08:42:53 #120 №470019 
>>470014
Да, данными обмениваться через json.
Аноним 28/04/15 Втр 08:55:02 #121 №470021 
Кто-нибудь может накидать простейшего, самого элементарного объяснения того, как работает последний OpenID (можно на английском)? В общем, я сейчас написал приложение, подумал, что было бы здорово подключить логин через Стим, пакетов под мой фреймворк ноль, чтобы зареквайерить и забыть, потому что меня уже изрядно тошнит от приложения и надо его заканчивать, поэтому решил посмотреть в сторону каких-то более классических библиотек и понять, как работает сам OpenID, потому что в голове каша полнейшая; сколько ни читаю, понять не получается.

У меня в программе есть таблица с пользователями и таблица с предложениями пользователей, связаны, как один-ко-многим через user_id в таблице с предложениями. Вот, например, заходит на сайте человек через Стим, как определить через if, что зашёл? Потому что, то, что я видел, с логина Стима идёт редирект на запрашивающий разрешения на вход сайт с кучей информации в самой ссылке, что с ней делать? Еще, нужно ведь при такой конфигурации БД заносить строчку с пользователем Стима в таблицу пользователей, потому что к ней привязаны предложения из соответствующей таблицы?

Спасибо, а то запутался что-то, вчера столько времени потерял, чтобы разобраться, но толком ничего в голове не отложилось.
Аноним 28/04/15 Втр 08:58:28 #122 №470022 
14302007085270.jpg
Кароче, вчера мне в голову пришла охуительная идея на момент прихода точно казалась мне таковой

Скоро лето, и те кто ищут работу, могли бы сделать себе футболку с принтом в таком духе: "ищу работу php-программиста" Ну можно даже задизайнить на сером фоне пару тегов уровня <?php echo ""; ?>
Ну и летом гонять в ней по людным местам, вдруг взлетит.
Аноним 28/04/15 Втр 09:04:21 #123 №470026 
>>470022

Не очень идейка.
Аноним 28/04/15 Втр 09:17:00 #124 №470028 
>>470022
Увижу - пизды дам.
Аноним 28/04/15 Втр 09:22:46 #125 №470031 
>>470026
почему не очень? Думаешь ЗАСМЕЮТ?

>>470028
Ну это уже толсто

Вы просто еще работу не пробовали искать, будучи дном без опыта. Когда 100 рзюме разослал, и тебе 2 ответа.
Аноним 28/04/15 Втр 09:30:07 #126 №470035 
>>470031

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

Это ты на какие вакансии рассылаешь?
Аноним 28/04/15 Втр 09:44:40 #127 №470038 
>>469828

> пишем не так как на голом пхп с созданием объекта через
> $object = new Class;
Там то же самое, просто оно чуть менее явно написано. Вот смотри, ты сказал

> пишется в конфигах
> $autoload['model'] = array('user', 'post', 'site');
Давай посмотрим в коде, как это обрабатывается. Вот класс Loader (объект этот класса хранится в $this->load и отвечает за загрузку и создание разных объектов, вроде моделей, вью и тд):

https://github.com/bcit-ci/CodeIgniter/blob/master/system/core/Loader.php#L1248
Тут мы загружаем конфиг автозагрузки:

> if (file_exists(APPPATH.'config/autoload.php'))
> {
> include(APPPATH.'config/autoload.php');
> }

https://github.com/bcit-ci/CodeIgniter/blob/master/system/core/Loader.php#L1316
Тут мы подгружаем указанные в нем модели:
> if (isset($autoload['model']))
> {
> $this->model($autoload['model']);
> }

Давай еще посмотрим код метода model:

https://github.com/bcit-ci/CodeIgniter/blob/master/system/core/Loader.php#L234

Тут проверяется не передан ли нам массив, и если да, то мы вызваем метод model для каждого элемента:

> if (is_array($model))
> {
> foreach ($model as $key => $value)

Затем подключаются файлы модели и базового класса CI_Model, и наконец создается объект:

https://github.com/bcit-ci/CodeIgniter/blob/master/system/core/Loader.php#L305
> $CI->$name = new $model();

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

И объекты тут точно такие же, с теми же полями и методами.

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

Ну и разумеется и конфиг autoload, и метод model описаны в документации по CI. Ну и даже без документации, взглянув в исходники, видно как это работает.

Ну и еще раз напомню, что этот подход с $this->load в современных фреймворках не используется.

> А просто описывается новый класс, но объект не создается, и
Объект создается, ты просто этого не нашел/не знал. Ну, теперь знаешь.
Аноним 28/04/15 Втр 09:51:08 #128 №470039 
>>469828

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

Автозагрузчик избавляет от необходимости писать руками require/require_once/$this->load

Мануал

http://php.net/manual/ru/function.spl-autoload-register.php
http://habrahabr.ru/post/136761/

То что в CI это другое, это как раз загрузчик для тех версий PHP где автозагрузки еще не было. Я же написал что CI довольно древний.
Аноним 28/04/15 Втр 10:07:28 #129 №470043 
>>469828

> у нас таблицы были сделаны на Myisam,
> конвертировал все таблички в innoDB
Правильно сделал, MyISAM древний и примитивный движок и в 99% случаев проигрывает innoDB. Он еще и транзакции не поддерживает и плохо работает в многопоточной среде.

Ну и внешние ключи сэкономят тебе время на исправлении битых связей в базе, так что их стоит добавлять. И тот, кто будет после тебя изучать базу, сможет увидеть связи. Не забывай еще комментарии к колонкам и таблицам добавлять, если их смысл не очень очевиден. И не забудь что в MySQL много интересных типов данных вроде DATETIME, YEAR, ENUM и не надо все делать только INT и VARCHAR: http://phpclub.ru/mysql/doc/column-types.html

>>469836

Ты можешь открыть АПИ фейсбука или вконтакте и скопировать оттуда. Зачем изобретать велосипед?

> И сами колонки как можно назвать одним словом само 'отношение к бухлу'
drinking habits может?

>>469853

Не обязательно. Ты, как я понимаю. на EAV (Entity- Attribute-Value) намекаешь? Она используется когда полей очень много и неэффективно их в виде колонок делать. Но тут у нас полей не так много, они там почти все обязательные, так что проще их ENUM сделать, с ним работать проще.

>>469927

Если полей относительно немного, проще в таблице ENUM хранить, запросы короче и удобнее будут.

>>469940

> Не проще ли сделать просто массивы соответствий?
Ты неправильные вещи советуешь. Вот смотришь ты на дамп базы а там

1
2
3
2
1

И что это значит? В этом неудобно разбираться и ориентироваться. Для полей в которых несколько вариантов есть тип ENUM:

material_status ENUM ('rich', 'poor') NOT NULL

В коде разумеется мы, как добропорядочные программисты, используем для этих значений константы (и заодно получаем автодополнение от IDE):

$user->setMaterialStatus(User::MATERIAL_STATUS_RICH);

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

> чем плодить кучу таблиц и связей в базе.
Есть тип ENUM

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

> Они просто будут лежать по сути мертвым грузом, и лишь жрать ресурсы сервера,
С ресурсами как раз проблем нет, если есть желание, то можно просто закешировать в быстром кеше вроде APCu или Memcache эти массивы и не лазать каждый раз в базу. По сути будет тот же массив, только не описанный руками, а взятый из базы. Ну например если городов немного то можно их закешировать. Можно не кешировать, так как выборка их по id тоже очень быстро работает.

Аноним 28/04/15 Втр 10:35:02 #130 №470052 
>>469946

В MySQL есть ENUM для этого

>>469951

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

Насчет вконтакте — ты прав, там не используются стандартные подходы, потому что у них большой объем данных, и огромная нагрузка и один сервер с базой данных не выдержит ее (но на раннем этапе, первая версия использовала обычный MySQL без наворотов). Данные надо разносить на тысячи серверов (шардинг), и это очень сложная штука. Плюс, некоторые данные хранятся не в базе, а в написанных ими на Си NoSQL хранилищах (код есть на гитхабе). Но это исключительные случаи, в 99% случаев подходы «из учебников» работают отлично. Ну и разумеется я уверен что разработчики вконтакте эти стандартные подходы прекрасно знают.

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

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

>>469963

> например выходит у тебя объект user
> и у него поля
> и где-то есть массив
Это пример того как делать не надо. Есть ENUM и константы. Вот удовольствие потом искать и догадываться где какой массив чему соовтетствует.

> Пол: <?= echo lang['sex'][user->sex] ?>
А надо так: <?= $user->getSexAsString() ?> или так: <?= $userHelper->printSexAsString($user) ?>

Перевод тоже делается не так. То, что ты придумал, это опять же велосипед на массивах. Для переводов есть open source расширение gettext (которое используется не только в PHP, но и например почти во всех linux утилитах). И с ним в качестве ключа используется английская версия строки:

<p><?= gettext('Sex', $domain) ?></p>

Где $domain это что-то вроде файла, откуда брать перевод. разумеется, напрямую использовать gettext не обязательно и можно написать свою обертку поверх него. А можно пойти дальше и встроить поддержку переводов в шаблонизатор (я не видел ни одного такого, но когда-то пытался навелосипедить что-то вроде этого. Сейчас я бы не стал делать велосипед, а расширил какой-нибудь твиг и отправил авторам пулл реквест):

<p>[[Sex:]]</p>

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

Сами переводы хранятся в файлах формата .mo для которых есть open source редакторы. Разумеется, текстовые строки не надо вписывать туда руками, я писал скрипт который обходил исходный код и собирал строки в mo файл на английском, после чего с него делался русский перевод.

Потом там еще нужны функции для подстановки в строку значений и склонения чисел. Ну например чтобы сделать переводимую фразу «5 человек написали 3 комментария» придется чуть исхитриться, так как слова склоняются в зависимости от чисел (а глаголы в зависимости от пола). gettext это не поддерживает, но у нас есть расширение intl, пришедшее из явы, где такая возможность есть, там свой синтаксис и эта фраза пишется примерно так:

{peopleCount, plural, offset:1
=0 {никто не оставил}
=1 {{peopleCount} человек оставил}
=2 {{peopleCount} человека оставили}
=3 {{peopleCount} человек оставили}
}

{commentCount, plural, offset:1
=0 {ни одного комментария}
=1 {{commentCount} комментарий}
=2 {{commentCount} комментария}
=3 {{commentCount} комментариев}
}

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

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

Кстати, если тебе интересны какие-то вопросы по локализации, я могу подсказать. Это все же учебный тред и наша цель обучать людей, а не просто говоирть что они поступают неправильно.
Аноним 28/04/15 Втр 10:41:37 #131 №470056 
посоны, помогите советом, мне нужно сделать, чтобы пользователь жал на кнопку "ознакомлен" и это записовалось в бд, подскажите как лучше организовать таблицы, пользователей будет много. И каждый должен будет "ознакамливаться". Писать их айди в столбец через запятую?
Аноним 28/04/15 Втр 10:49:21 #132 №470057 
>>469963
Мне тоже такой подход с массивом в конфиге казался логичным. А вот нихрена, читнул еще с десяток источников, буквально все настаивают что все данные надо хранить в бд. Нагруженность и прочее это все с их слов решается кешированием, хотя я толком еще не знаю как оно работает.
>>470043
Читал про enum тоже, тут пишут что это отстой http://komlenic.com/244/8-reasons-why-mysqls-enum-data-type-is-evil/
>EAV (Entity- Attribute-Value)
Вот это мне даже больше понравилось то о чем >>469853 писал. И мне даже подсказали как одним красивым запросом потом получить что-то типа 'мужчина, пьет, не курит, разведен' т. е. строка из всех значений вот этих опций с указанием сепаратора, например запятой. Но дальше с ней делать нечего, порядок опций произвольный может прийти 'мужчина, курит, пьет', а может 'пьет, мужчина, курит', короче распарсить это нереально.
Короче буду делать отдельные таблицы да и все.

Аноним 28/04/15 Втр 11:32:46 #133 №470066 
>>470057

Статья показывает только отрицательные стороны и довольно однобока.

Плюсы ENUM: запросы получаются проще и нагляднее, не нужны джойны.

> 1. Data isn't being treated like data.
не согласен, ENUM можно считать отдельным типом c ограниченным наборром значений. Как он там внутри хранится, не принципиально, так как мы этого не видим.

> 2. Changing the member list of ENUM columns is very expensive.
Если только добавлять новые значения то не дорого. Если менять то да, но точно так же дорого менять любую другую колонку, не только ENUM. Да и вряд ли у тебя будут миллиарды записей, а если у тебя их миллион ты просто ночью на минуту поставишь заглушку на сайт (или может быть на минуту запретишь обновлять профили) и сделаешь миграцию.

> 3. It's impossible to add additional attributes or related info
если тебе надо добавлять дополнительные аттрибуты (или значений много), не используй ENUM. Ну например для городов конечно надо делать отдельную таблицу.

> 4. Getting a list of distinct ENUM members is a pain.
Это да, обычно этот список просто прописывается в коде. Ну например пол или материальное положение не меняется каждый день и их можно прописать константами.

> 5. ENUM columns may only offer limited or negligible effects on optimization
А никто и не говорил что он для оптимизации, он для упрощения запросов. Зачем создавать лишнюю таблицу если можно не создавать?

> You can't reuse the member-list of an ENUM column in other tables.
да, но это как правило никогда и не требуется

> ENUM columns have noteable gotchas.
> Suppose you have ENUM('blue', 'black', 'red') and you attempt to insert 'purple': MySQL actually truncates the illegal value to ' ' (an empty string)

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

> пример с числами
Согласен, подвох, но я и не предлагаю использовать числовые ключи

> 8. ENUM has limited portability to other DBMS
Перенос на другую ДБ это такая боль, что ENUM тут особой роли не играет. Ну и если ты используешь константы в коде, то тебе надо будет поменять только значения в них. Если ты изолируешь код работы с БД в одном слое классов, то опять же это будет проще.

Ну и автор не написал про недостатки подхода с отдельной таблицей. Допустим, у нас есть «семейное положение», реализованное отдельной таблицей. Как в коде поставить статус «женат»? Откуда мы узнаем id этого статуса?

В случае с ENUM все просто: у нас есть константа

const STATUS_MARRIED = 'married';

В случае с таблицей мы как-то должны руками приписать id, что гораздо непонятнее.

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

> И мне даже подсказали как одним красивым запросом потом получить что-то типа 'мужчина, пьет, не курит, разведен' т. е. строка из всех значений вот этих опций с указанием сепаратора
А тебе рассказали что в MySQL ограничение на длину строки GROUP_CONCAT, по моему по умолчанию в 1024 байта если не меньше? Будь осторожен, если ты например используешь его для получения списка id (например id всех друзей пользователя) то лишние id просто молча обрежутся.

> короче распарсить это нереально.
И не надо. Это изначально неправильно, надо выбирать их как отдельные поля.

>>EAV (Entity- Attribute-Value)
Это обычно используется когда очень много атрибутов и не все обязательные. Ну например свойства товаров: у монитора есть размер диагонали, а у чайника нет, зато есть объем и мощность.

Впрочем можно и к анкете пользователя применить, особенно если там очень много пунктов.

Выбирать атрибуты из EAV проще всего отдельным запросом, вроде SELECT ... FROM user_attributes WHERE user_id = :user_id и потом на стороне PHP разгребать полученный массив. Ну и при таком подходе потом кеш будет проще добавить.
Аноним 28/04/15 Втр 11:33:43 #134 №470067 
>>470056

Отношение многие-ко-многим между пользователями и сообщениями, через отдельную таблицу.
Аноним 28/04/15 Втр 11:50:51 #135 №470071 
Пыханы-крутаны

Почему такое :

$tags = $this->get('request')->query->get('tags') ;
// echo '<pre>';
$factQB
->leftJoin('f.tags', 't')
->add('where', $factQB->expr()->in('t.id', array(':tags')))
->setParameter( 'tags', $tags);

выдаёт такое :

[2015-04-28 11:50:27] request.CRITICAL: Uncaught PHP Exception Doctrine\ORM\Query\QueryException: "Invalid parameter number: number of bound variables does not match number of tokens" at /var/www/factcloud/vendor/doctrine/orm/lib/Doctrine/ORM/Query/QueryException.php line 100 {"exception":"[object] (Doctrine\\ORM\\Query\\QueryException: Invalid parameter number: number of bound variables does not match number of tokens at /var/www/factcloud/vendor/doctrine/orm/lib/Doctrine/ORM/Query/QueryException.php:100)"} []


???HALP????
Аноним 28/04/15 Втр 12:09:20 #136 №470076 
>>470021

Почитать немного можно тут

http://help.yandex.ru/openid/index.xml
http://openidexplained.com/
http://stackoverflow.com/a/353892
http://media.techtarget.com/tss/static/articles/content/OpenID/clientdiagram1.gif

Вот спецификация, много букв: https://openid.net/specs/openid-authentication-2_0.html

Суть OpenID в том что вместо регистрации на сайте ты вписываешь свой логин на каком-то openid провайдере (сервисе), например:

cat.livejournal.com
openid.yandex.ru/vasya (не уверен что верно написал)

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

Преимущество openid в том что он очень открытый и децентрализованный: тебе не надо договариваться с провайдерами или получать у каждого ключи, чтобы залогинивать их пользователей. Если ты хочешь стать провайдером, тебе не надо нигде получать разрешение. Ты можешь сам стать провайдером и логиниться везде через свой собственный сайт, храня все данные у себя. У Oauth которым пользуются соцсети, такой открытости и близко нет.

Логин тут имеет форму URL и для некоторых пользователей это сложно, помнить его. Потому для них придумали дополнительную опцию, когда пользователь жмет «зайти через яндекс», его отправляют на яндекс, там он логинится и дает разрешение, и его перенаправляет назад на сайт залогиненным. Разница в том, что не надо помнить и вводить на сайте свой openId, он тут спрятан от пользователя. Забыл, как это называется.

Есть у OpenId и недостатки.

Теперь подробнее.

Логин, как видишь, имеет форму URL и на этот URL можно отправлять специальные запросы. Если провайдер действительно поддерживает OpenID то в странице полученной с этого URL будут специальные заголовки или метатеги с нужной информацией (например с URL на который надо слать запросы или перенаправлять пользователя). Этот процесс проверки называется «discovery».

К примеру если открыть исходный код cat.livejournal.com то увидим:

<link rel="openid2.provider" href="http://www.livejournal.com/openid/server.bml" />
<link rel="openid.server" href="http://www.livejournal.com/openid/server.bml" />
<meta http-equiv="X-XRDS-Location" content="http://cat.livejournal.com/data/yadis" />

Это говорит о том что LJ поддерживает openId и указанный URL cat.livejournal.com является OpenID идентификатором пользователя на этом сервисе. В метатегах прописаны точки API для взаимодействия, то есть куда слать запросы.

Вот исходный код с яндекса, openid.yandex.ru/vasya/

<link rel="openid2.provider" href="http://openid.yandex.ru/server/" />
<link rel="openid2.local_id" href="http://openid.yandex.ru/vasya/" />
<link rel="openid.server" href="http://openid.yandex.ru/server/" />
<meta http-equiv="X-XRDS-Location" content="http://openid.yandex.ru/vasya/yadis/" />

Ок, мы получили адреса API (этот процесс назывался discovery). Теперь через API мы получаем адрес страницы, куда надо редиректить пользователя чтобы он дал разрешение передать данные. Это называется Authentication request. Получив его, мы редиректим пользователя. Если все ок. то сайт отредиректит пользователя назад к нам, добавив в URL одноразовую метку (если все плохо то он отредиректит пользователя к нам передав код ошибки). Имея метку, мы напрямую отправляем запрос и по этой метке получаем данные пользователя, и можем создать для него аккаунт или залогинить.

Если пользователь уже давал согласие то после редиректа к провайдеру тот сразу же редиректит пользователя назад к нам с меткой.

Если что-то непонятно, учточняй.

> Еще, нужно ведь при такой конфигурации БД заносить строчку с пользователем Стима в таблицу пользователей, потому что к ней привязаны предложения из соответствующей таблицы?
Внешние логины делают через отдельную таблицу со связью много-к-одному к таблице пользователей.

Аноним 28/04/15 Втр 12:18:43 #137 №470077 
>>470014

— Не индексируется поисковиками
— при ошибке JS пользователь ничего не увидит и сайт просто не будет реагировать не на что, неприятно. По моему интуитивному ощущениею 99% разработчиков не умеют и не мониторят клиентские ошибки.
— если не реализуешь работу с URL то не будет работать история, переходы вперед/назад, обновление страницы, поделиться ссылочкой, закладки
— получаешь кучу сложностей вместо того чтобы сделать просто и логично. Ты можешь с сервера отдавать страницы сразу, а зачем-то вместо этого городишь какие-то приложения, JSON, клиентский рендеринг и прочие сложности. Зачем? чтобы в твоем коде труднее было разбираться и чтобы его дольше было писать? По такой логике, давай еще пару сервисов добавим и несколько API, чтобы сервер тоже не брал данные напрямую из базы, а обращался к третьему API какому-нибудь.

API обычно используют для взаимодействия между отдельными сервисами.

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

> какой фрейморвк использовать для серверного php
Yii 2 вполне подойдет.
Аноним 28/04/15 Втр 13:09:01 #138 №470089 
>>470071

В сообщении написано же

> number of bound variables does not match number of tokens
Число плейсхолдеров не соответствует числу заданных через SetParameter параметров.

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

$sql = $factQB->getSql( );
var_dump($sql);

Посчитать число плейсхолдеров.

Потом сдампить $tags и посмотреть что в нем.

Ну и дальше если непонятно, пиши в тред с подробностями, подумаем еще.
Аноним 28/04/15 Втр 13:51:47 #139 №470108 
REST API + angular / ember / другая-js параша это кстати сейчас реально стильно модно молодежно, не слушай этих старых пердунов.
Аноним 28/04/15 Втр 14:42:42 #140 №470130 
Анончики, запутался в регулярках на исправление знаков препинания в задаче Shift, подскажите плз.
https://ideone.com/3MTsk9
ОП 28/04/15 Втр 14:49:54 #141 №470134 
Интересная статья, какие наказания бывают в компаниях: http://m.siliconrus.com/2015/04/punishment-2/

Готовься, анон!
Аноним 28/04/15 Втр 15:25:44 #142 №470149 
>>470134
Прикольно.
Аноним 28/04/15 Втр 16:14:03 #143 №470174 
>>470035
>Это ты на какие вакансии рассылаешь?
php - разработчик, лол.

>Нет, просто шансы таким способом найти работу стремятся к нулю.
Ну я понимаю блин, но вдруг прокатит.
Аноним 28/04/15 Втр 16:18:40 #144 №470177 
>>470174

Ну так сразу php-разработчиком не берут, т.к. опыта и знаний нет, то может стоит для начала джуном пойти работать, чтобы этот самый опыт и знания получить?
Аноним 28/04/15 Втр 18:14:07 #145 №470239 
>>470066
Тогда замучу пол и семейные отношения на enum по идее это вообще никогда трогать не надо будет, а всякие привычки на отдельных таблицах заодно посмотрим с чем будет больше гемора.
Аноним 28/04/15 Втр 18:45:17 #146 №470247 
Аноны, помогите, как сделать, чтобы в задании "grammar Nazi" с регуляторными выражениями выдавало ошибку? http://ideone.com/zkATLp
Аноним 28/04/15 Втр 19:10:07 #147 №470256 
>>470177
Ну так ясно же что джуном пытался, в общем проехали.
Аноним 28/04/15 Втр 19:35:48 #148 №470273 
>>470256

Да не поверю, что такая хуйня на самом деле. Какой город?
Аноним 28/04/15 Втр 20:08:13 #149 №470294 
>>470273
Новосиб, я тут уже кулстори пилил два раза, вот взяли как раз, нделю уже работаю.
Аноним 28/04/15 Втр 20:15:07 #150 №470302 
>>470294

Блять, хуево. Я как раз собираюсь летом в Новосиб перебираться. Неужели так все печально? Вроде объявления смотрел, требования везде довольно божеские.
Аноним 28/04/15 Втр 20:40:27 #151 №470340 
>>470302
Не, все норм. Просто я реально начинающий был. Вот тут мониторь например. Можешь заранее написать большинству этих контор и попросить тестовые задания как будешь собираться переезжать. http://rabota.ngs.ru/vacancy?q=php

Алсо для человека который решил все задачи из треда или посмотрел курсы специалиста полностью не будет сложным за недельку справиться с любым из них. Одним например нужно сделать блог с маломальским дизайном, другим админку. В общем если ты уже что-то умеешь то найдешь себе работу. Еще есть конторы в Академе, и там кадровый голод постоянный, пиши им. Можешь даже просто открыть 2_гис, найти там "Технопарк" И звонить во все конторы которые в нем и в окрестных домах базируются и предлагать себя, лол.
Аноним 28/04/15 Втр 20:53:14 #152 №470356 
>>470340

А, ну тогда норм. Переезжать где-то в июле наверное буду, так что еще пару месяцев есть на то, чтобы выучить все что нужно для трудоустройства.
Аноним 28/04/15 Втр 22:11:14 #153 №470394 
Есть ли тут аноны изучающие одновременно 2 языка - JS и PHP? Не путайтесь?
Аноним 28/04/15 Втр 22:16:58 #154 №470395 
Медленно продолжаю пилить фалообменник. На сегодня зделал пока это
https://github.com/tokotun/uppy
>>466105


>По поводу класса File: мне кажется, не надо было объединять классы, а надо было работу с медиаданными поместить в класс MeiaInfo.
>Ведь в ООП объект это данные + методы для работы с ними и медиаданные тянут на отдельный объект.
>Но если у тебя есть причины оставить это в классе File, можно оставить.

-----Мне не понравилось, что классу file приходится вызывать посторониие функции, для обработки данных в своём поле.


>>466108
>Вот тут довольно хитро вычисляется путь. Ты берешь не максимального ребенка комментария, а максимального потомка:
> https://github.com/tokotun/uppy/blob/master/uppy/app/CommentsMapper.php#L62
>Было бы наверно гораздо проще, если бы было поле parent_id и мы могли взять максимального из детей с указанным parent_id, и увеличить последнюю цифру в нем.

Теперь сделал чуть проще. И берутся только ребёнки. И увеличивается последняя цифра в пути.Подойдёт?

>В PDO есть функция lastInsertId http://php.net/manual/ru/pdo.lastinsertid.php
Я так понял эта функция берёт id последней вставленной строки. То есть сначала вставляем информацию о файле в БД, и только потом сохраняем файл на сервер.
С тем ID, под которым была сохранена информация о файле в БД.

>Ты не учел что картинки бывают в разных форматах.
https://github.com/tokotun/uppy/blob/master/uppy/app/Uploader.php#L62
Это сейчас все форматы так перечислять? Вижу что код будет повторятся, но лучше придумать не могу.
Аноним 28/04/15 Втр 22:40:14 #155 №470407 
>>469571
Очевидный Специалист с Борисовым же(вроде 2014 года - без вырезок и норм).1 и 2 уровень - мастхев, в 3-ем говорится об ооп и так по мелочи. Но в ООП я бы вьезжал по другому руководству. Есть еще за 2010 - там совсем все разжевано и много говорится о подводных камнях, про приведение типов тоже много, как помню. Все, что непонятно можно прочесть в Котерове. На перых парах должно хватить.
Аноним 29/04/15 Срд 00:02:28 #156 №470453 
ОПчик, дорогой, я треды совсем не мониторю, но не мог бы ты меня проконсультировать.
Я могу сказать, что если я знаю, как работает технология, то схватываю информацию по ней на лету.

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

И ещё, я много читал информации по ООП. Вроде, всё логично и очевидно, но если открою чужой код, то очень теряюсь. в частности, я не обрёл дзен, и не очень понимаю, зачем это всё.

Аноним 29/04/15 Срд 00:20:49 #157 №470462 
Часто на современных сайтах вижу кнопки которые вроде и не ссылки и вроде и не часть формы, но что-то делают именно на бекенде. Например в твиттере есть кнопки "читать" - это и не ссылки, и не input type=submit, в html это просто button. При нажатии они подписывают вас на обновления, то есть это работа именно с сервером. Как же они работают? Догадываюсь что на них навешиваются события, по клику отправляется ajax-запрос на сервер, если прошло нормально то во фронте просто меняется на другое состояние("уже читаю"). Я прав?
Аноним 29/04/15 Срд 01:34:57 #158 №470479 
>>470462
да
Аноним 29/04/15 Срд 03:21:05 #159 №470489 
>>469805

> никаких суперзнаний не надо.
ну так да, знаний CSS достаточно, суперзнаний и не надо

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

Без хорошего знания PHP/ООП ничего не выйдет. Ты можешь сам попробовать это сделать и проверить что получится.

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

>>469812

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

Аноним 29/04/15 Срд 03:29:12 #160 №470491 
>>469989

В программе что-то у тебя мало выходит, там во втором банке около 61270.

> $bank[2];
Вот это плохая идея, так писать, так как ничего не понятно, что значит «2»? Надо либо использовать имена для ключей вроде $bank['percent'] либо, что лучше, вообще не использовать массив, а передавать обычными переменными.

> $balance = $balance + $percent
Проценты надо прибавлять по другому, надо прибавлять не 0.04 рубля (или гривны), а 0.04 от суммы долга.


> Какой редактор кода для PHP имеет такую же хипстерскую подсветку
По моему во всех редакторах подсветка задается темой, и в интернете можно найти любые темы, и светлые на темном, и темные на светлом.

> Где можно почитать об аккуратности оформления кода?
В стандартах PSR которые приняли разработчики основных фреймворков. В принципе там даже текст читать не обязательно, на примерах кода все видно:

http://www.php-fig.org/psr/psr-1/ru/
http://www.php-fig.org/psr/psr-2/ru/

(все переведено на русский)

> Насколько для форматирования пригоден Phpformatter?
Вроде как пригоден, также если у тебя IDE то там скорее всего есть горячая клавиша для форматирования, а в настройках можно выбрать стиль. Это удобнее. Вот горячие клавиши: https://gist.github.com/codedokode/8759492

Аноним 29/04/15 Срд 03:35:32 #161 №470492 
>>469989

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

>>470022

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

>>470130

Причина вот этом месте:

> [,!\.\?][^\s]
Тут регулярка при совпадении съедает запятую и идущую за ней букву. Я думаю, лучше поменять подход на такой. Ищем

(любое число пробелов)(знак)(любое число пробелов)

и заменяем это на

(знак)(1 пробел)

Ну и preg-split тут наверно не очень подходит, заменять лучше через preg_replace. Чтобы не потерять знак, используй скобки и подстановки вроде $1 в выражении для замены.



Аноним 29/04/15 Срд 03:42:23 #162 №470493 
>>470174

А тебя до выполнения тестового задания/вопросов отсеивают или после? Если после то значит знаний маловато и надо их улучшать.

>>470247

> for ($i = 0; $mistake1Counter!=$i; $i++){
Тут ошибка. preg_match_all кладет результат в массив массивов (2-мерный массив), а ты пишешь:

$mistake1Counter!=$i

$mistake1Counter это массив, а $i число, как можно их сравнивать? что ты ждешь от этого? Массив конечно всегда будет не равен числу.

Ты можешь увидеть что в $mistake1Counter с помощью команды

var_dump($mistake1Counter );

Там, как ты видишь массив массивов. Причем preg_match_all может расположить элементы в нем 2 разными способами, они описаны в мануале: http://php.net/manual/ru/function.preg-match-all.php

Если ты не знаешь, как вывести все элементы из него, то тебе надо вспомнить foreach и может быть перечитать урок про массивы.

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

Есличто-то еще непонятно, задавай вопросы
Аноним 29/04/15 Срд 03:52:32 #163 №470495 
>>470395

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

Таким образом это бы выглядело примерно так:

$file->mediaData->getBitrate( );

> Теперь сделал чуть проще. И берутся только ребёнки.
ну пусть будет так. Только функцию strToArr я бы переименовал более понятно например pathToString или pathToArray

> То есть сначала вставляем информацию о файле в БД, и только потом сохраняем файл на сервер.
Разумеется, ты не можешь получить id пока не вставишь запись. Зато мы избегаем гонки при многопоточной работе (а веб приложения многопоточные). Да и как иначе? SELECT MAX/SELECT COUNT не работает так как в промежутке между вызовом SELECT и INSERT в базе может появиться сколько угодно новых записей.

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

>Это сейчас все форматы так перечислять?
Там всего 3 формата, JPG, GIF, PNG, это немного.

> imagecopyresampled($thumb, $source, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
Это копипастить не надо.

> imagejpeg($thumb, "{$this->uploadPath}thumbs/$filename");
превьюшки не обязатеьно в том же формате сохранять.

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

> if ($mime == 'image/jpeg'){
> if ($mime == 'image/gif'){
> if ($mime == 'image/png'){
Это уместнее писать через if/elseif чтобы была видна связь между блоками. И что если ни один вариант не выполнится?
Аноним 29/04/15 Срд 03:55:06 #164 №470496 
>>470453

> информацию по роутингу
Slim, Slilex, Symfony Routing. Сейчас в каждом фреймворке свой роутер + можно поискать отдельную библиоетку на сайте phptrends.

> правам доступа
ACL, Symfony aCL, опять же на phptrends поискать

> Желательно был бы материал, в котором описывается поэтапно написание своего.
Гугли по фразам «writing router in php» и аналогично на русском, может где то есть туториал, но я не уверен.

> Вроде, всё логично и очевидно, но если открою чужой код, то очень теряюсь
Может ты берешься за сложное? Открываешь код на фреймворке не изучив документацию на сам фреймворк?


Аноним 29/04/15 Срд 03:55:43 #165 №470497 
>>470462

> Догадываюсь что на них навешиваются события, по клику отправляется ajax-запрос на сервер, если прошло нормально то во фронте просто меняется на другое состояние("уже читаю")
да, это все яваскрипт

Аноним 29/04/15 Срд 03:56:26 #166 №470498 
>>470453

А права доступа еще наызваются RBAC, Role Based Access Control
Аноним 29/04/15 Срд 08:55:17 #167 №470525 
>>470492
> Чтобы не потерять знак, используй скобки и подстановки вроде $1 в выражении для замены.
Я не знал что нужно разбивать всю регулярку по скобкам, и чтобы не потерять часть ставить кроме $1, еще и $2.
https://ideone.com/HURfqM
Аноним 29/04/15 Срд 09:43:08 #168 №470540 
14302897882580.jpg
>>470496
>>470498

Спасибо, дорогой!
Аноним 29/04/15 Срд 11:44:49 #169 №470589 
>>470525
Йода https://ideone.com/eDCJIK
Аноним 29/04/15 Срд 13:48:41 #170 №470650 
обработчики не срабатывают, если установлены на элементы подгруженные через аякс. Но работают, если функции тоже подгрузить через аякс. Но это ведь не вариант, это лишний вес. Как быть?
Аноним 29/04/15 Срд 15:40:35 #171 №470710 
>>470650

Ты так описал проблему, что я еле понял. И при этом не приложил пример кода.

> обработчики не срабатывают, если установлены на элементы подгруженные через аякс.
Если они установлены то они сработают. В твоем случае ты их наверно просто не установил.

> Но работают, если функции тоже подгрузить через аякс.
???

> Как быть?
После вставки элементов в страницу поставить на них нужные обработчики. Или, что умнее, использовать делегирование, по моему через метод .on() который ставит обработчик на родительский элемент, и ловит всплывающие события.

Вот прочти этот раздел для начала, так как я вижу что ты события знаешь очень плохо и тебе надо начать с теории: https://learn.javascript.ru/events-and-interfaces

Когда прочтешь, то скорее всего сам догадаешься что делать. Если нет, пиши.
Аноним 29/04/15 Срд 15:49:13 #172 №470716 
>>470525

программа работает, это хорошо, но я думаю, надо ее чуть упростить еще.

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

Я вижу, ты сообразительный. Попробуй подумать, как совместить 2 этих действия в одно:

> Исправляем ошибку вида "слово, " и " ,слово"
> Исправляем ошибку вида "слово,слово"

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

> if ($key > 0) {
> $result = $result . ". " . $sentence;
В таких случаях проще части предлоежений складывать в масиив, а после цикла объединить его в строку через implode.

Аноним 29/04/15 Срд 15:56:48 #173 №470719 
>>470395

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

https://github.com/tokotun/uppy/compare/master@%7B2015-04-20%7D...master

Это показывает например что ты сделал за последнюю неделю.

Мануал: https://help.github.com/articles/comparing-commits-across-time/

Разумеется то же самое можно сделать без гитхаба, в гите в командной строке: git diff 6c6c6d780 master
Аноним 29/04/15 Срд 16:17:24 #174 №470734 
>>470395

Вот еще по мелочам:

> uppy/container/×.×
Точка в линуксе не имеет особого значения и можно писать просто × (или нельзя? скрытые файлы начинающиеся с точки не попадут в список? я не помню). А твое выражение как раз соответствует не всем файлам, а только если в имени есть точка. Файл Makefile например ему не соответствует

Потом еще гляну.
Аноним 29/04/15 Срд 16:20:41 #175 №470737 
Господа, как gearman правильно настроить?
Уже кучу туторов перерыл и вот такое мне кидает

2015/04/29 15:57:24 [error] 3127#0: *7128 FastCGI sent in stderr: "PHP message: PHP Fatal error: Class 'GearmanClient' not found in /var/www/factcloud/vendor/mmoreram/gearman-bundle/Mmoreram/GearmanBundle/Service/GearmanClient.php on line 232" while reading response header from upstream, client: 127.0.0.1, server: factcloud.localhost, request: "POST /app_dev.php/registration HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "factcloud.localhost", referrer: "http://factcloud.localhost/app_dev.php/registration"
Аноним 29/04/15 Срд 16:52:16 #176 №470750 
Не понял, а как в задачке про Вектор среднее искать? Среднее на департамент или сотрудника? Или что? Просто если среднее арифметическое искать, т.е. сложить все и на количество поделить, то ответы нифига не сходятся с результатом.
Аноним 29/04/15 Срд 17:01:49 #177 №470751 
>>470750

Алсо, как добавлять такую кучу работников? Неужели через циклы?
Аноним 29/04/15 Срд 17:19:09 #178 №470756 
>>470751
я функцию завел, которая добавляла работников каких и сколько ей прикажешь. Внутри был цикл, да. Выполнялся столько раз, сколько работников требовалось.
Подглядывай если совсем туго будет, ну и естественно можно не только таким способом делать
http://ideone.com/IsAdmu
>>470750
Среднее по департаменту же, считаешь сначала сколько всего во всей конторе, там как раз строчкой выше надо посчитать, и делишь на количество департаментов. Изи.
Аноним 29/04/15 Срд 17:41:15 #179 №470768 
>>470756

Ну я так и думал, что через цикл. Просто думал, мб другие методы есть. И дык проблема то там в том, что в результате ОП-а получается не общая сумма деленная на количество департаментов, а совсем другое число.
Аноним 29/04/15 Срд 18:12:57 #180 №470795 
>>470737

Напиши как ты устанавливал Gearman? Просто строчку в composer.json добавил?

также, дай ссылку на документацию геармана, на инструкцию по установке.

Я в сети вижу упоминание какого-то pecl extension, ты его не устанавливал?

>>470750

> Среднее на департамент или сотрудника?
число бумаг или кофе или потраченных денег — среднее среди 4 департаментов.

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

>>470768

ОП программу не запускал и числа выдумал

Аноним 29/04/15 Срд 18:17:08 #181 №470797 
>>470795

Подскажи, как складывать результаты работы функции. Т.е. записываю я

$employees = Employee::createEmployee(9, 'manager', 1, 'purchases');
$employees = Employee::createEmployee(3, 'manager', 2, 'purchases');

Но оно не складывается в один массив, а вторая строка перезаписывает первую.
Аноним 29/04/15 Срд 19:41:42 #182 №470844 
>>470797

Все, разобрался.
Аноним 29/04/15 Срд 19:48:43 #183 №470849 
>>470797

Вот так у меня http://ideone.com/1bKAij
Аноним 29/04/15 Срд 19:49:02 #184 №470850 
>>470844
Ну и покажи как ты сделал, интересно же
Аноним 29/04/15 Срд 20:15:01 #185 №470859 
Аноны, поясните по вордпресс, пару дней назад начал всё это дело учить, на примере натягивания макета на вордпресс. Появилась идея попробовать перенести сайт на вордпресс, сайт представляет собой доску объявлений, вроде бы интуитивно догадываюсь что надо делать, но там такой момент надо прицепить форму которая бы все данные писала в базу данных? Поясните, для этого одного натягивания темы не хватит? Надо писать собственные плагины для этого?
Аноним 29/04/15 Срд 20:16:16 #186 №470860 
Проясните за безопасность. Например залогиненый пользователь изменяет настройки профиля, нужно вызвать соответствующую функцию и передать в нее айди. Откуда брать айди? Логично что из сессии, но не сможет ли туда злоумышленник подсунуть чужой айди? Вообще существует ли возможность из клиента как-то редактировать сессию?
Аноним 29/04/15 Срд 21:27:33 #187 №470885 
>>470859
Зависит от функционала, а вообще, думаю, что можно, но не только тему нужно будет нятануть. Я вообще только что плагин закончил писать, как первое задания, для вордпресса.
Аноним 29/04/15 Срд 21:36:03 #188 №470893 
>>470859

Вордпресс не подходит для этого.

> Надо писать собственные плагины для этого?
да, весь функционал доски объявлений придется реализовать плагином.

>>470860

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

>>470797

$array[] = $element чтобы добавить элемент к конец массива
Аноним 29/04/15 Срд 21:57:46 #189 №470910 
>>470885
Что за плагин написал? Тоже хочу написать плагин, может кто заданием поделится по плагинам для вордпресс?
Аноним 29/04/15 Срд 22:26:31 #190 №470923 
Сделал задачу про Вектор. Проверяй, ОП.

http://ideone.com/nfmsSX
sageАноним 29/04/15 Срд 23:05:57 #191 №470966 
>>470923
говно
слишкм много текста
Аноним 29/04/15 Срд 23:09:34 #192 №470971 
Кротаны, поясните за вывод из базы данных при помощи вордпресс. Вот пишу в плагине такое:

function out() {

$posts = $wpdb->get_results("SELECT ID, post_title FROM $wpdb->posts WHERE post_status = 'publish'
AND post_type='post' ORDER BY comment_count DESC LIMIT 0,4");
return $posts;

}
add_action('the_content', 'out');

Выбивает ошибку, говорит что это не объект, точнее выводит вот это:

Call to a member function get_results() on a non-object

Если выводить просто без хука то выводит нормально, тут конечно всё очевидно но я не могу въехать только начал изучать вордпресс, может кто подсказать?
Аноним 29/04/15 Срд 23:10:43 #193 №470972 
>>470966

echo "Пошел нахуй";
Аноним 30/04/15 Чтв 00:03:50 #194 №470994 
Как перестать заниматься хуетой и начать заниматься делом?
Спасибо.
Аноним 30/04/15 Чтв 06:17:55 #195 №471062 
>>470994

Хуй знает, анон. Я знаю, как прокрастинация может жизнь попортить, сам постоянно от нее страдаю. Но в последнее время довольно легко заставить себя учить, т.к. меня уже тошнит от моего мухосранска и от рашки в целом. И если начинаю лениться, то просто смотрю в окно и это чувство отвращения дает мне импульс для того, чтобы заняться делом.
Аноним 30/04/15 Чтв 08:12:34 #196 №471069 
ОП, я так долго не писал потому что не мог понять кое что в задаче про кошек-мышек.
С одной стороны, все твои замечания понятны, с другой, я даже не знаю как сформулировать вопрос, поэтому решил написать как есть.

Вот смотри:
Прошлый раз ты предлагал избавиться от массива $map и сделать универсальный алгоритм для выбора ходов »467892 »468288
Допустим мы избавились от массива $map, заменив его на SplObjectStorage со всеми Животными, и оставим параметры ширины и высоты.
Допустим мы хотим сделать ход каким-то Животным. Для этого мы сначала получаем новый SplObjectStorage с Животными, которые попадают в обзор.
И тут у меня происходит ступор
»467892
>— оцениваем каждый ход в баллах
Как оценить каждый ход? Ведь всяких различных вариаций разных ходов очень-очень много! Может быть по 3-4 Кошки (если ход делается Мышкой), может начаться Котовый Апокалипсис, в котором в 90% клеток будут Кошки, могут появиться сверх быстрые и зрячие мышки, которые видят всю карту и могут за один ход переместиться в любое место на карте... И как из этого всего узнать какой ход наиболее выгодный? Как рассчитать наибольшее расстояние от всех кошек сразу?
Аноним 30/04/15 Чтв 08:16:28 #197 №471072 
>>471062
Такое же дерьмо. Даже нечего добавить - мотивируют только негативные ощущения.
Аноним 30/04/15 Чтв 09:00:12 #198 №471078 
>>470795

>>470795
>
>Напиши как ты устанавливал Gearman? Просто строчку в composer.json добавил?

>также, дай ссылку на документацию геармана, на инструкцию по установке.

>Я в сети вижу упоминание какого-то pecl extension, ты его не устанавливал?
Спасибо, уже разобрался. Мой судо, какой то не судо и не хочет некоторые штуки0 делать
Аноним 30/04/15 Чтв 09:32:16 #199 №471093 
>>468317
Привет анон. Тут есть чуваки использующие Zend framework 2? Мне нужно понять зачем нужны и стоит ли использовать hydrators. Судя по всему гидратор используется чтобы в контроллере изящно закачать данные из формы в объект одним методом, вместо построенного сохранения. Однако для этого приходится реализовывать этот интерфейс в моделях с методами гидрации и закачки и в итоге ты нихуя не выигрываешь да еще и грузишь лишним модель - MVC way модель объекта не должно волновать как с ней будут взаимодействовать. Сущность ради сущности? Ооп ради ооп?
Или я упускаю что-то? Поясни плз бро нахуя это нужно в Zend framework 2?
Аноним 30/04/15 Чтв 13:11:27 #200 №471146 
>>471069

> Для этого мы сначала получаем новый SplObjectStorage с Животными, которые попадают в обзор.
простого массива хватит наверно, но можно и SplObjectSt.

> Как оценить каждый ход? Ведь всяких различных вариаций разных ходов очень-очень много!
У мышки выбор из 5 вариантов:

— остаться на месте
— влево
— вверх
— вправо
— вниз

У кошки не более 9 вариантов хода. Это немного.

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

> И как из этого всего узнать какой ход наиболее выгодный?
Оценит каждый ход в баллах и сделать выбор.

Ну вот пример, допустим мы мышка, у нас есть 5 вариантов хода, мы можем оценить выгоду хода на клеточку X так:

— берем расстояние от X до ближайшей кошки. За каждую клеточку добавляем 100 баллов. то есть если например от X до кошки 4 клетки то получается 400 баллов. Если кошек вообще нет то добавляем 500 баллов.

— берем число кошек видимое из X и за каждую вычитаем 3 балла, но не более 60 в сумме.

— берем число возможных ходов из клетки X (то есть свободных клеточек) и за каждую прибавляем 10 баллов. Например из угловой клетки всего 2 выхода, а из центральной 4 выхода.

Таким образом если от X до ближайшей кошки 4 клетки, из нее видно 3 кошки и есть 3 выхода, то получается 400 - 3 + 30 = 427 баллов.

Аналогично мы считаем баллы для других клеточек и решаем на какую сходить.

> Ведь всяких различных вариаций разных ходов очень-очень много!
Не более 9 вариантов при нынешних правилах.

> Может быть по 3-4 Кошки
ну и пусть

> может начаться Котовый Апокалипсис, в котором в 90% клеток будут Кошки,
И что? Алгоритм не справится? Я думаю, справится.

> Как рассчитать наибольшее расстояние от всех кошек сразу?
Найти ближайшую. Нас интересует расстояние до ближайшей кошки, а не до самой дальней.
Аноним 30/04/15 Чтв 13:14:01 #201 №471148 
>>471093

Доки читал?
http://zf2.com.ua/doc/65

Написано, что это просто интерфейс для загрузки данных из модели или в модель в виде массива. Использовать можно как угодно, в том числе и для работы с формами. Если не надо то ты его реализовывать и использовать не обязан.
Аноним 30/04/15 Чтв 16:38:29 #202 №471271 
>>470971
если ты хочешь отфильтровать посты то лучше сделать так: https://codex.wordpress.org/Plugin_API/Filter_Reference/posts_where
Аноним 30/04/15 Чтв 17:10:40 #203 №471311 
Допустим есть база с такими таблицами:
film (id, name)
category(id, name)
film_category(id_film, id_category)
фильмы, категории и их связь, задача: выбрать фильмы состоящие в выбранных категориях (допустим id этих категорий 1 и 2) я делаю так:

SELECT FROM film WHERE (SELECT COUNT() FROM film_category WHERE film_category.id_film = film.id AND film_category.id_category IN (1,2)) = 2

есть ли способ проще?
Аноним 30/04/15 Чтв 18:30:42 #204 №471384 
>>471271
Спасибо за ссылку, я просто хочу разобраться как работать с базой данных в вордпресс. Например как вывести что то из базы данных в the_content
Аноним 30/04/15 Чтв 18:56:43 #205 №471404 
>>471384
сформулируй конкретную задачу, в зависимости от неё не всегда нужны чистые sql запросы, иногда можно воспользоваться средствами wp (и лучше потому что чем меньше своего суешь тем легче потом разбираться в этом другим и тем это безопаснее, я так считаю)
Аноним 30/04/15 Чтв 19:40:21 #206 №471425 
>>471404
Мне сейчас самое элементарное, допустим есть база данных с некоторыми значениями, как вывести эти данные в поле the_content()
Аноним 30/04/15 Чтв 19:40:46 #207 №471426 
Опчик, ну еще за одну штуку просвети. Это я, изобретатель ORM. Вот есть сущность - User. 30 полей, в них может быть много текста, для выборки всех нужных данных из базы применяется серьезный такой запрос с несколькими джоинами. Когда нужно показать профиль - деваться некуда, выбирать нужно все. Но есть страницы где достаточно аватарки и имени, например когда юзер показывается как друг в чужом профайле, или как член сообщества куда он вступил. Несколько напрягает то что для этих целей создаются полноценные экземпляры класса. Куда логичнее было бы получать только то что нужно. И тут приходят в голову два варианта.
1. Дополнительный класс, какой-нибудь UserCustom, только с id и name. Не нравится он мне тем что этот класс по смыслу дублирует обычный User. Да и странно что маппер будет возвращать два разных объекта, то есть одинаковых по смыслу но с разными именами. И не универсально; для другой страницы может еще город понадобиться, не напасешься таких классов. Короче, это ерунда, я уже понял.
2. Дополнительный метод у маппера, а не класс. Но возвращаем все равно User. Просто вместо монструозного
getUser() {
sql = 'SELECT * ... FROM users LEFT JOIN cities ... LEFT JOIN ... LEFT JOIN ... ';
делаем getCustomUser(array $fields) {
$fields = implode($fields, ', ');
sql = "SELECT $fields FROM users WHERE id = ?";
+ универсально, для разных страниц можно выбирать свои наборы полей
- несколько запутано
3. Тоже самое, только под каждый набор полей отдельный осмысленный метод. Например
getUserAsFriend() {
sql = "SELECT $id, $name ..."; //для отображения в списке друзей
getUserAsMember() {
sql = "SELECT $id, $name, $phone ... //для отображения в списке членов группы
getUserAsCandidate() {
sql = "SELECT $id, $name, $city, $family_status... //для отображения в списке поиска для знакомств, допустим
- несколько однотипных методов, хотя по идее слишком много и не надо
+ все кристально понятно и симпатично
Однако объединяет их один жирный минус про который ты как-то говорил. Методы класса должны возвращать предсказуемый, актуальный результат, нельзя чтобы user->getAge() возвращал пустой массив из-за того что возраст не присвоили. Я все методы переделал под магический __get(), но все равно странно что в одной вьюхе у User-a можно обращаться к чему угодно, в другой к имени и городу, а в третьей еще к чему-то. Хотя вроде как в этом и была вся задумка.
Аноним 30/04/15 Чтв 19:54:54 #208 №471429 
Котаны, а тут можно задавать вопросы по js? А то js-тред, похоже, того.
Аноним 30/04/15 Чтв 20:04:26 #209 №471432 
>>471426
>изобретатель ORM
Грузи непосредственные данные сущности каждый раз. Связные сущности грузи лениво. Сделай интерфейс для возможности жадной загрузки связей.

мимо
Аноним 30/04/15 Чтв 20:32:52 #210 №471439 
>>471432
Нуу, сейчас у меня затык не в этом, загрузка связанных сущностей кое-как реализована. Вопрос вот в чем, если очень кратко: есть большой, сложный (относительно) объект, в зависимости от ситуации он может быть нужен как целиком так и 1-2 его свойства. Вот если нужны 1-2 свойства, как лучше поступить - специальный метод, в кач-ве параметров принимающий требуемые поля или несколько методов с заранее в них определенными наборами свойств. В любом их этих вариантов тот большой сложный объект возвращается как бы полупустым, что мне не нравится, с другой стороны в этом и есть смысл. Я уверен что в ООП эта задача часто встает, но чет не могу нагуглить. А может не надо мудрить а всякий раз возвращать все подряд свойства. Ну кроме связанных если они не нужны.
Аноним 30/04/15 Чтв 20:39:49 #211 №471441 
Извините аноны за тупые вопросы по вордпресс, ну вот ещё один. Я понял как выводить данные из БД на страницу, нашёл вот такой метод:

function out() {

global $wpdb;
$table_item = $wpdb->prefix.worm_item;
$posts = $wpdb->get_results("SELECT*FROM $table_item");
foreach ($posts as $post) {
echo $post->name;
echo "<br>";
}

}

add_filter('the_content', 'out');

Я понимаю что это кажется немного не безопасный метод, правильнее использовать ООП и наверное дата мапер (его можно использовать в вордпресс?). Но вопрос не в этом, вопрос в том как сделать каждую запись из таблицы отдельным постом? У меня они высвечиваются все в каждой записи а мне надо что бы каждая строка была отдельной записью? Как это можно сделать без изменений в теме? Я так понимаю что то надо менять в этой части?

add_filter('the_content', 'out');

Что то надо ставить вместо the_content ?
Аноним 30/04/15 Чтв 20:49:03 #212 №471443 
>>471062
Совет не очень, но все-таки.
Аноним 30/04/15 Чтв 21:11:34 #213 №471446 
14304174940440.jpg
Аноны, где можно скачать бесплатно и без регистрации. В гугле только отрывок нашел.
Аноним 30/04/15 Чтв 21:14:50 #214 №471448 
>>471439
Не нужно мудрить. Для тех, кто используют орм, производительность dal стоит не на первом месте, иначе бы они денормализовали бд и запускали спшки через минимально возможную прослойку кода.

А на счет вытаскивания пары свойств — it depends. Если эта пара свойств дергается примерно так же часто, как и полноценный тяжелый объект, и просадка производительности критична, то имеет смысл это место оптимизировать. Если это делается через орм, то дать возможность выполнения кастомного сиквел кода или запуска спшки с мапингом на соответствующую сущность (типа UserInfo, а не User).
Аноним 30/04/15 Чтв 21:43:51 #215 №471455 
>>471439
А вообще, то, что ты пишешь
>getUserAsCandidate(), getUserAsMember() etc
это не орм, а обычный интерфейс dal, где методы пишутся под конкретные use cases.

>специальный метод, в кач-ве параметров принимающий требуемые поля
Тут тоже интересный момент, зависящий от интерфейса твоего орм. Если ты планируешь нечто подобное:
[code]
context.users.where("$name = 'vasya'").join(context.userGroups, "$1.id = $2.userId").select("...")
[/code]
то все очевидно довольно-таки.

тред не читал, пхп забыл >>471448 - кун
Аноним 30/04/15 Чтв 22:04:08 #216 №471457 
где найти пхп макаку занедорого?
Аноним 30/04/15 Чтв 22:27:03 #217 №471466 
>>471457
Я бы с радостью попробовал совсем за недорого, то есть вообще бесплатно, но у меня наверное не очень хороший уровень, впринципе знаю основы ООП, могу написать корявый простой интернет-магазин, блог, доску объявлений впринципе тоже могу. Если не жалко потратить немного времени пиши на [email protected]
Аноним 01/05/15 Птн 08:44:01 #218 №471564 
В чем принципиальное различия middle от junior-а? Стек технологий? Архитектура? Код?
Аноним 01/05/15 Птн 08:56:10 #219 №471566 
>>471564
Опыт проектной работы.
Аноним 01/05/15 Птн 09:53:31 #220 №471578 
>>471566
Неужели если кто-то проработает 2 года он в категорию мидлов сразу перейдет? Фиг там.
sageАноним 01/05/15 Птн 10:13:22 #221 №471582 
У меня вопрос по PHPDoc.

/
@return \Vendor\Namespace\Something
/
public function getInstanceOfSomething()
{
return new Somethng();
}

Нужен ли тут слэш перед Vendor?

И еще.

/

@return this
/
public function getThis()
{
return $this;
}

Допустимо ли писать this? Или необходимо указывать неймспэйс\имя возвращаемого класса?
Аноним 01/05/15 Птн 10:13:39 #222 №471583 
>>471578
Да, перейдет. За 2 года можно и сеньором стать, если ты активный социоблядок.
Джун не от того джун, что йоба фреймворк не знает, а от того, что не знаком с процессами разработки по. От чего косячит и требует надзора.
Разница в уровне тех. скилла между джуном и интермедиатом — +- пара подводных камней.
Аноним 01/05/15 Птн 10:13:56 #223 №471584 
>>471582
Сажа прикреилась, разметка потерялась. Но суть вопроса ясна, думаю.
Аноним 01/05/15 Птн 11:16:50 #224 №471591 
14304682109100.jpg
>>471583
Что-то я тебе не верю, ибо хуёвые сказки ты травишь. Это, как тимлиды в 19 и сеньеры в 23, это, как ноют про то, что трейни предлагают сразу 700 баксов и социальный пакет. Все сказки, которые к реальности отношения не имеют. Думаешь, что джун сможет принимать архитектурные решения? Думаешь, что джун будет знать nosql хранилища и т.п.? Не будет такого. Конечно может, если речь о веб-студиях, ты прав, но в серьезных проектах это не так.
Аноним 01/05/15 Птн 13:08:02 #225 №471603 
>>470910

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

1) сделай плагин который позволяет задать «черный список» слов и выражений, которые считаются спамерскими. Комментарии с такими словами не должны публиковаться и сразу удаляться. При этом желательно не выводить сообщение об ошибке, а делать вид как будто все ок.

В админке должна быть отдельная страница, со списком слов и выражений, просто текстареа, каждое выражение с новой строки, и галочка или кнопка для включения/отключения плагина (можно не делать если это делается стандартными средствами вордпресса).

Выражения при сравнении игнорируют регистр букв, всякие небуквенные символы вроде запятых и html (а еще желательно чтобы нельзя было обойти список заменой русских букв на похожие латинские). То есть выражение «казино» соответствуют комментариям «заходите в КаЗиНо», «заходите в к.<b>а</b>.з.и.н.о.».

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

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

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

2) усложненная версия. Сделай кроме «черного» списка еще возможность высчитывать рейтинг доверия к комментаторам.

Принцип такой: у каждого пользователя есть рейтинг доверия, по умолчанию он равен 0. Рейтинг доверия показывает, сколько комментариев можно опубликовать без модерации. Каждый одобренный комментарий увеличивает рейтинг на k, k задается в админке и может быть дробным, по умолчанию k = 1. То есть:

— пользователя оставляет первый комментарий, он идет на модерацию
— после одобрения пользователь получает рейтинг k = 1 и оставляет второй комментарий без модерации
— после этого третий комментарий снова идет на модерацию
— после одобрения пользователь получает рейтинг = 2 и может оставить 2 комментария без премодерации
— после этого комментарий снова подвергается модерации
— после этого пользователь может следующие 3 комментария без модерации

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

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

В админке должно быть:

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

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

Если этот функционал можно сделать не отдельной страницей, а интегрировать в существующую админку пользователей, было бы здорово.

Пользователь идентифицируется по логину, если он зарегистрирован, если нет то по IP, то есть для анонимных пользователей рейтинг считается для Ip адреса.

замечания: тут скорее всего надо будет делать дополнительные таблицы в базе или добавлять колонки к существующим.

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

Что скажешь? Ту работы недели на 2-4 в неспешном темпе.

Код (только самого плагина) хорошо бы постить на гитхаб.
Аноним 01/05/15 Птн 13:26:38 #226 №471614 
Аноны, у меня сейчас мало времени, так что кого успею, того проверю, а остальных вечером или завтра. Не ждите меня, решайте задачки, читайте уроки, статьи и мануалы.

>>470923

> class Department
> public function createEmployee($amount, $profession, $rank, $chief = 0)
Это лучше вынести из департамента. каждый класс должен заниматься своим делом (принцип single responsibility: http://getinstance.info/articles/php/the-single-responsibility-principle/ )

Департамент не создает работников. Он принимает их на работу.

Более того, смотри, твой департамент не дает возможности просто добавить существующего работника в него:

$department = new Department('Название');
$employee = new Employee('manager', 3, 0);

// упс ... а как принять этого работника на работу в департамент?

Традиционно, когда один класс содержит объекты другого, у него делают методы вроде addEmployee($e) и removeEmployee($e) чтобы их можно было добавлять и удалять.

> $this->name = $name;
> $this->employees[]
Я не вижу где определено это поле. Конечно php автоматически создает поле при записи в него, но ты не должен так делать так как страдает читабельности и понятность код: я не могу увидеть список всех полей в классе не прочитав код целиком.

> public function DepartmentEmployeersNumber
В PHP принято писать функции с маленькой первой буквы и начинать с глагола в стиле сделайЧтоТо: getEmployeeCount


> if ($chief == 1) {
Для обознаечния понятий «да»/«нет» лучше использовать булевые(логические) значения true/false http://php.net/manual/ru/language.types.boolean.php

> return round ($this->DepartmentPayment() / $this->DepartmentPages(), 1);
Округлением должен заниматься тот кто выводит, а департамент должен возвращать точные данные. Ты же не знаешь какая точность нужна вызывающему эту функцию.

> if ($profession == 'manager') {
> $this->payment = 500;
> $this->coffee = 20;
> $this->pages = 200;
Боюсь, что это плохая идея. Во-первых, чтобы добавить новую профессию, нам надо править код функции и она будет разрастаться. Во-вторых при таком подходе мы не можем для одной профессии поменять формулу расчета зарплаты на другую.

Гораздо удобнее сделать не один класс Сотрудник, а 4 класса: Инженер, Менеджер, и т.д. Тогда мы можем легко менять например правила расчет зарплаты или кофе для каждой профессии. Естественно, копипастить одинаковый код в 4 класса не надо — создай базовый абстрактный класс Сотрудник и унаследуй от него 4 класса-профессии. Также в этом случае мы можем добавить новую профессию, добавив новый класс и не меняя существующий код.

Наследование позволяет создавать класс не с нуля. а расширяя существующий класс: http://php.net/manual/ru/language.oop5.inheritance.php

«Абстрактный» — это класс, объект которого нельзя создать. Он предназначен для наследования от него других классов: http://php.net/manual/ru/language.oop5.abstract.php

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

----

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

1. Сократить в каждом департаменте 40% (округляя в большую сторону) инженеров, преимущественно самого низкого ранга, которые не являются боссами.

2. Увеличить в целях стимуляции умственной деятельности базовую ставку аналитика с 800 до 1100 тугриков, а количество выпиваемого им кофе с 50 до 75 литров. В тех департаментах, где руководитель не является аналитиком, заменить его на аналитика самого высшего ранга из этого департамента (а бывшего руководителя вернуть к обычной работе)

3. В каждом департаменте повысить 50% (округляя в большую сторону) менеджеров 1-го и 2-го ранга на один ранг с целью расширить их полномочия.

Совет директоров в затруднении: какой путь выбрать? Помоги им с этим, распечатав прогноз по потреблению и расходам (аналогичный тому что требуется в задаче) после принятия каждой из мер.

----

Если что-то непонятно, справшивай.
Аноним 01/05/15 Птн 13:38:08 #227 №471618 
>>470971

> Call to a member function get_results() on a non-object
Это ошибка которая значит что $wpdb не является оьъектом и потому ты не можешь вызывать у нее методы. С помощью var_dump($wpdb); определи что там хранится.

Алсо, это случайно не внутри функции происходит? Ты знаешь что внутри функции по умолчанию глобальные переменные недоступны? Если нет то тебе сначала надо повторить как работают области видимости переменных в php и перечитать этот раздел мануала: http://php.net/manual/ru/language.variables.scope.php

>>471311

Это надо делать через джойны, подзапросы довольно неэффективны и плохо читаются.

http://www.anton-pribora.ru/articles/mysql/mysql-join
http://rche.ru/1009_razbiraemsya-s-sql-join-vizualnoe-predstavlenie.html

соответственно джойнишь фильмы на таблицу связи и пишешь SELECT film.id FROM ... JOIN ... WHERE fc.id_category IN (1,2);

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



Аноним 01/05/15 Птн 14:09:56 #228 №471633 
>>471425

Я мимо проходил, но вот тут пишут что это можно сделать как-то через add_filter: http://premium.wpmudev.org/forums/topic/how-do-i-add-data-into-the_content

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

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

>>471426

> Несколько напрягает то что для этих целей создаются полноценные экземпляры класса. Куда логичнее было бы получать только то что нужно.
Это тоже одна из проблем ORM, частичная выборка. Помни, что функции всегда должны возвращать актуальный и точный результат. Если ты создаешь объект у которого заполнена часть полей, и этот объект неотличим от заполненного, то будут проблемы.

В доктрине есть специальное слово PARTIAL для выборки частично заполненных объектов: http://odiszapc.ru/doctrine/dql-doctrine-query-language/#13241_partial

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

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

Также, сама концепция ORM предполагает что ты выбираешь из базы объекты (целиком), а не отдельные поля.

Соответственно для выборки части полей придется делать один из 2 вариантов:

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

— сделать ленивую загрузку некоторых полей из базы при первом обращении к ним. То есть мы выбираем объект с основными полями, а при обращении к ленивым идут дополнительные запросы. Для этого разумеется код должен это поддерживать, например использовать геттеры-сеттеры вместо публичных полей. Ленивую загрузку можно реализовать так: ленивые поля хранятся завернутыми в прокси-объект, который знает, загружено поле или нет и если нет, то у него есть ссылка на маппер для загрузки поля:

// создаем объект в маппере
$user = new User( );
$user->setName($name); // не ленивое поле
$proxy = FieldProxy::createLazy($this, 'community', $user); // объект оборачивающий ленивое поле который полезет в базу при попытке чтения
$user->setCommunityProxy($proxy);

// прокси с уже проставленным значением которое не полезет в базу
$firendsProxy = FieldProxy::createWithValue($friends);
$user->setFriendsproxy($friendsProxy);

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

Соответственно в классе $user мы при попытке прочитать ленивое поле обращаемся к прокси объекту:

public function getCommunity()
{
return $this->community->getValue( ); // вызывает SQL запрос через маппер если поле еще не загружено
}

public function setCommunity($community)
{
$this->community->setValue($communtiy);
}

Как видишь, это требует некоторого усложнения кода. Также при ленивой загрузке мы можем получить проблему N + 1 запроса (если мы в цикле проходимся по массиву пользователей и обращаемся к их ленивым полям).

Но вернемся назад: а так ли нам нужны ленивые поля? намного ли медленнее выбирать все поля? У нас, в IT мире не принято в таких случаях верить словам или ощущениям, а принято делать тесты. Диванные оптимизаторы тут не нужны. Раз уж ты заговорил про оптимизацию, то подкрепи свои слова таблицами и графиками.

Сделай таблицу, например с 100 000 записей со случайными значениями (хинт: вставлять по 1000 записей одной транзакцией быстрее чем 1000 отдельных). Затем напиши 2 варианта кода, которые в цикле например 1000 раз выбирают случайную запись. Первый вариант кода выбирает все поля, второй только часть. замерь время выполнения обоих. Если хочешь, можно еще выполнять этот код для разного числа итераций (от 1 до 100000) и по ним построить красивый график к екселе/опеноффисе.

Заметь что генерация случайных чисел в больших количествах требует времени. Чтобы это не влияло на тест, лучше сгенерировать массив случайных id для выборки до теста.

Заметь что есть разница в способе хранения больших полей типа TEXT. Потому если ты не загружаешь поля типа TEXT (особенно если в них много данных), разница может быть больше, чем если не загружать поля типа INT или VARCHAR.

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

Аноним 01/05/15 Птн 14:20:37 #229 №471639 
>>471426

> Дополнительный класс, какой-нибудь UserCustom,
Это создает путаницу так как пользователь может быть представлен в 2 видах. плучается будет часть функций которым нужен USer, а часть которым UserCustom? даже если унаследовать User от UserCustom, будет не очень удобно.

И как ты будешь делать связи? Например у комментария есть метод getUser, ты сделаешь второй метод getUserCustom? И что ты будешь делать если полный User не загружен, а мы вызваем getUser?

Вообще, в доктрине есть «легкие» прокси-объекты, которые хранят только id, они называются Reference. Доктрина генерирует эти классы как наследников классов которые они представляют. То есть Reference для User это класс-наследник User (и потмоу это нормально работает с тайп-хинтами и instanceof и ты можешь передать User Reference везде где нужен User). И как только ты пытаешься вызвать любой метод кроме getId(), происходит обращение к базе, и объект заполняется данными.

Вот мануал: http://doctrine-orm.readthedocs.org/en/latest/reference/advanced-configuration.html#reference-proxies

// создаем reference без данных из базы, только в id
$item = $em->getReference('MyProject\Model\Item', $itemId);

// добавляем к другому объекту
$cart->addItem($item);

// а вот тут произойдет запрос к базе и заполенние полей
echo $item->getName( );

> Дополнительный метод у маппера, а не класс. Но возвращаем все равно User.
Не забывай что методы User должны возвращать актуальную и точную информацию независимо от того как он создан. Недопустимо чтобы например $user->getFriends не возвращал друзей если они есть.

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

>все кристально понятно и симпатично
Верный путь к бардаку и багам.

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

>>471429

Да

Аноним 01/05/15 Птн 14:23:16 #230 №471640 
>>471439

> Вот если нужны 1-2 свойства,
Может просто загрузить их в виде массива? Или же пиши прокси-объект, мне кажется у него код будет не сложный, там всего несколько публичных методов: получить знаечние, задать значение. И если значения нет то он обращается к мапперу и запрашивает его из базы.

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

> А может не надо мудрить а всякий раз возвращать все подряд свойства
Сделай сначала тесты и посмотрим какая разница в скорости.
Аноним 01/05/15 Птн 14:32:09 #231 №471647 
>>471441

Ты делаешь неправильно. Фильтр не должен ничего выводить на страницу, он должен возвращать результат через reutrn

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

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

Смотри примеры кода в документации: https://codex.wordpress.org/Function_Reference/add_filter (читал ли ты ее? надо читать)

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

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

> У меня они высвечиваются все в каждой записи а мне надо что бы каждая строка была отдельной записью?
Фильтр не для этого. Фильтр для изменения текста каждой выводимой записи. Например добавить информацию об авторе в конец поста или заменить коды в тексте на картинки.

Алсо, сформулируй что тебе надо сделать понятно, потому что я пока ничего не понял.
Аноним 01/05/15 Птн 14:39:51 #232 №471655 
>>471446

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

>>471448

> иначе бы они денормализовали бд
Ты не видел БД автора вопроса а уже предлагаешь ее денормализовать.

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

Технология для ленивой загрузки объектов/полей реализуется через прокси-объекты. В Доктрине например есть прокси-объект Entity reference.

>>471457

В лесах Африки.

>>471466

Если у тебя есть лишнее время лучше тратить его на изучение и выполнение каких-то учебных задач, а не на выполнение примитивной работы. Это примерно то же самое что если ты хочешь стать инженером и идешь на стройку разнорабочим набраться опыта. У нас в первом посте есть задания, в том числе например на Yii,если ты его уже знаешь ,могу скинуть ссылку на туториал по Симфони 2 ( http://symfony.in.ua/symfony2-jobeet-tutorial.html нужно знание ООП/MVC ).

Аноним 01/05/15 Птн 14:44:17 #233 №471659 
>>471564

Опыт и уровень самостоятельности.

>>471582

Я много раз видел, пишут @return self, так что думаю допустимо. Также (это мое личное мнение) @return self лучше не писать, так как любая нормальная IDE должна это уметь распознавать сама.

self упомянут в документации: http://phpdoc.org/docs/latest/references/phpdoc/types.html

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

Вот это упомянуто: http://phpdoc.org/docs/latest/references/phpdoc/types.html#valid-class-name

> Нужен ли тут слэш перед Vendor?
Зависит от того какие у тебя namespace/use стоят. Правила такие же как в обычном коде.

Аноним 01/05/15 Птн 14:48:46 #234 №471661 
>>471583

> За 2 года можно и сеньором стать,
Если ты живешь в стране 23 летних сеньоров?

>>471591

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

Аноним 01/05/15 Птн 15:06:01 #235 №471667 
>>471633
>Ленивую загрузку можно реализовать так: ленивые поля хранятся завернутыми в прокси-объект, который знает, загружено поле или нет и если нет, то у него есть ссылка на маппер для загрузки поля
Так-так, щас, я уже почти все понял. Но как этот прокси-объект поймет загружено поле или нет? isset($this->{$field}) всегда вернет true потому что поле объявляется одновременно с экземпляром
class User {
private $id,$name,$phone...
}
empty() и ==NULL тоже не подходит, поля могут быть просто не заполнены если юзер что-то не указал
Получается что все равно надо хранить какой-то список filledFields.
Аноним 01/05/15 Птн 15:13:26 #236 №471669 
>>471667

> isset($this->{$field}) всегда вернет true
А зачем тебе isset? Ты должен обращаться к прокси-полям особо, не как к обычным. То есть нужна поддержка со стороны класса User, он должен знать что такие-то поля реализованы через прокси. Можно просто их список сделать.

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

public function getSomething()
{
return $this->somethingProxy->getvalue( );
}

И соответственно проверить это поле можно так:

$value = $user->getSomething( );
if (empty($value)) [
...
}

> Получается что все равно надо хранить какой-то список filledFields.
Информация о том загружено ли значение хранится внутри прокси. ПРимерно так:

public function getValue()
{
if (!$this->isDataLoaded) {
$this->loadValueFromDb( );
}

return $this->value;
}

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

И еще раз напомню про тесты: сделай тесты. Я не увреен что от реализации ленивых полей есть выигрыш. От ленивых связей наверно он есть, а вот насчет полей не уверен.
Аноним 01/05/15 Птн 15:26:16 #237 №471671 
>>471667

Кстати, с прокси придется еще сделать чтобы работал такой сценарий:

$user = $mapper->find(1); // загружаем пользователя с минимумом полей

$user->setSomething('aaa'); // обновляем прокси-поле, обращения к БД не должно быть так как мы записываем новое знаечние

$mapper->save($user); // маппер должен увидеть прокси-поля в объекте, и он должен сохранить в базу только измененные, то есть только поле someting, а другие не трогать. Если он попытается получить значения не загруженных полей, пойдут лишние SELECT запросы.
Аноним 01/05/15 Птн 16:02:24 #238 №471681 
>>471669
>То есть нужна поддержка со стороны класса User, он должен знать что такие-то поля реализованы через прокси. Можно просто их список сделать.
Тогда, пожалуй, это не то что мне хотелось. Точнее под мой хитрый план надо делать все поля с возможностью ленивой загрузки. Ну потому что, в том примере где мне нужно только имя и айди все остальные поля выходит что должны быть ленивыми. А они задуманы, судя по всему, для полей которые достаются из других таблиц, в этом случае можно выгадать какую-то оптимизацию. А, вспомнил, ты в прошлом треде про что-то такое писал и тот чел что первый мне ответил тоже самое имел ввиду. Нее, это не так круто как хотелось бы.
Тогда облегченный объект. minifiedUser, userPreview, userAvatar (в значении 'представлениеПользователя', а не 'картинкаПользователя')
>плучается будет часть функций которым нужен USer, а часть которым UserCustom?
Нннет. Единственное предназначение этого мини-юзера быть переданным во вью и показать там аватарку + имя. Больше он нигде не будет использоваться, вызываться, передаваться.
Ну или массив.
Аноним 01/05/15 Птн 17:21:06 #239 №471700 
>>471681

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

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

Не забудь сделать чтобы User наследовался от MiniUser — тогда его можно будет передавать в работающие с ним функции.

> Ну или массив.
Бардак будет

Аноним 01/05/15 Птн 18:15:19 #240 №471717 
14304933198480.jpg
14304933198501.jpg
14304933198502.jpg
Анон, помоги ньюфагу. Прости, если не туда зашёл, но я уже всю голову сломал.

Аноним 01/05/15 Птн 18:16:03 #241 №471719 
14304933632650.jpg
>>471700
Я не настолько крут чтобы так сразу представить как сделать тесты. Зароюсь еще в них и тебя лишний раз задолбаю, а тут и так все туговато идет. Главное чтоб хуже не было, зато у меня все по фен-шую теперь: весь профайл - О Тоторо, превьюшки - тиби тоторо.
Аноним 01/05/15 Птн 18:16:59 #242 №471720 
>>471717
name должно быть не у формы, а у инпута
Аноним 01/05/15 Птн 18:25:05 #243 №471726 
14304939057120.jpg
>>471720

Так ведь? Не помогло.
Аноним 01/05/15 Птн 18:44:58 #244 №471735 
>>471726
У другого инпута.
Аноним 01/05/15 Птн 19:52:38 #245 №471770 
14304991580650.jpg
>>471735

Спасибо, анончик, заработало. У меня есть ещё вопрос, если позволите. Пикрелейтед-код шлёт в COM порт значение ползунка с html от 0 - 255, я не уверен в том, что переменная будет считываться функцией exec вообще. Данные-то отправляются, я вижу это по мигающиму светодиоду на переходнике usb-uart, но вот считывается ли переменная или отправляется как просто набор символов я не знаю.
Аноним 01/05/15 Птн 19:58:26 #246 №471771 
>>471770
если пост запросом отправить ; rm -rf / ; то пизда системе, не?

мимонезнакомспхп
Аноним 01/05/15 Птн 20:03:30 #247 №471772 
>>471771
Я сам не знаком с ним. Хочу сделать управляемый через сеть RGB светильник.
Аноним 01/05/15 Птн 20:55:15 #248 №471781 
>>471771

да. У него уязвимость позволяющая выполнить любу. команду, только под виндой не rm rf а что-то другое надо писать, например format d:


>>471770

Тебе лучше сначала PHP и HTML изучить хотя бы на базовом уровне. Иначе ты так будешь на каждой мелкой проблеме тупить и ошибок наделаешь. А со знаниями PHP все быстро и правильно сделаешь.

> но вот считывается ли переменная или отправляется как просто набор символов я не знаю.
перенпараввь вывод в файл вместо порта и посмотри
Аноним 01/05/15 Птн 20:55:52 #249 №471782 
>>471772

Пока твой светильник позволяет только скачать тебе троян на компьютер через сеть.
Аноним 01/05/15 Птн 20:57:29 #250 №471783 
>>471719

Так тест несложно сделать:

$start = microtime(true);
for ($i = от 1 до N) {
делаем действие, например выбор случайной записи;
}
$end = microtime(true);
$timePassed = $end - $start;

echo $timePassed;




Аноним 01/05/15 Птн 21:20:57 #251 №471788 
Задача: дан текст, содержащий слова на русском и английском языках. В некоторых словах часть русских букв заменена на похожие на них латинские, и наоборот. Напиши программу, которая находит все такие слова, выводит их и выделяет квадратными скобками первую замененную букву.

Почему элемент массива не преобразуется в строку?
http://ideone.com/Fhk7ki
Аноним 01/05/15 Птн 21:34:20 #252 №471796 
>>471788
в implode нужно передавать массив. А у тебя передается значение в $matches2[0] == string(13) "трaляля"
Аноним 01/05/15 Птн 21:35:01 #253 №471797 
>>471788
http://php.net/manual/ru/function.implode.php
Не забывай смотреть в документацию
Аноним 01/05/15 Птн 22:05:51 #254 №471811 
http://ideone.com/3iW75h

В чем фейл? куда теряется D?
sageАноним 01/05/15 Птн 23:29:07 #255 №471861 
>>471811
Покажи мне хоть одно коммерчески успешное приложение на D.
Аноним 01/05/15 Птн 23:49:42 #256 №471879 
>>471719

Насчет MiniUser: тут есть загвоздка в том, что когда ты захочешь загрузить полную информацию о пользователе, у тебя будет 2 объекта относящихся к одному пользователю: MiniUser и User и дублирование это конечно не очень хорошо.

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

Мы можем разбить класс Пользователь на 2 части: основная информация о пользователе (User) + все остальное (Profile). Так как эти части связаны, то логично Profile поместить внутрь юзера примерно так:

echo $user->getName( );
echo $user->getProfile( )->getSomething( );

Ну и особенность тут в том, что объект $profile мы можем грузить лениво. То есть мы можем засунуть его в прокси,и это позволяет нам либо грузить только маленький набор полей (только User), либо полный (User + Profile). Прокси скрывает от нас все это и загружает Profile лениво при первом обращении к нему.

Код выглядит примерно так:

public function getProfile()
{
return $this->profileProxy->getValue( );
}

Конечно еще есть вариант сделать без прокси и выбрасывать исключение при попытке вызвать getProfile если Pofile не загружен:

public function getProfile()
{
if (!$this->profile) {
throw new \Exception("You have not load profile for user id = $this->id");
}

return $this->profile;
}

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

Соответственно так же, через прокси можно загружать связи пользователя с другими объектами. Прокси дает тебе выбор, грузить данные жадно, сразу или лениво, по мере надобности, прозрачно для работающего с объектом кода.
Аноним 01/05/15 Птн 23:53:12 #257 №471886 
>>471811

> $dataC = parent::__construct($data);
Конструктор по задумке ничего не возвращает. Соответственно если ты нарушаешь это разумное правило то приготовься страдать.

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

Алсо, там еще одна логическая ошибка:

> ($dataA = false)
> $dataA .= "A";
ты определись, что тут у тебя, строка или логические значения
Аноним 01/05/15 Птн 23:54:40 #258 №471889 
>>471811

И что по твоему должно было получиться? Вроде с виду все нормально.
sageАноним 02/05/15 Суб 00:04:51 #259 №471903 
Зашел, молча всех обоссал и вышел из треда.
Аноним 02/05/15 Суб 00:24:26 #260 №471917 
>>471886
>>471889

Да я уже поправил код после этого, пока час никто не отвечал. Спасибо.
Просто хотел понять как передавать инфу от родителя потомку и от потомка к родителю.
Аноним 02/05/15 Суб 05:48:04 #261 №471991 
>>471879

Я канеш хуй знает, т.к. новичок еще, но как насчет того, чтобы передавать функции какое-то значение и в зависимости от этого значения выводить только нужную инфу? Т.е. пишем что-нибудь типа this->getProfile('profile') и он выводит то, что нужно. Если другая инфа нужна, то пишем this->getProfile('full_info').
Аноним 02/05/15 Суб 10:24:05 #262 №472029 
>>471782
Это каким образом? Разве сервер позволяет редактировать код? Насколько я знаю он даже php файл не отображает.

Аноним 02/05/15 Суб 10:42:34 #263 №472031 
Что делать с фреймворком. Как я понимаю у нас в СНГ, довольно популярный Yii2,
но вообще, кто к чему склоняется? Что насчет Laravel? Про Symphony 2 думать не хочу, он слишком монстр, как по мне(хотя
если есть здравые аргументыв его пользу, то можно переубедить). Да, кстати, что еще подскажите по-поводу ORM? Есть ли у
php какие-то годные? Сейчас я занимаюсь тем, что работаю на удаленке допиливая всякую хрень, вроде плагинов для wordpress-а
и думаю поискать работу в офисе, а для неё лучше бы всего какой-нибудь фреймворк знать.
Аноним 02/05/15 Суб 10:44:59 #264 №472033 
>>471991
Ты принцип инкапсуляци этим соблюдать не будешь. Почитай об ООП, для каждого поля класса нужен отедльный геттер и сэттер. За то, что ты предложил нужно руки отрывать, потому, что поддерживать такой код сложно
Аноним 02/05/15 Суб 10:47:08 #265 №472034 
>>471781
> да. У него уязвимость позволяющая выполнить любу. команду, только под виндой не rm rf а что-то другое надо писать, например format d:

Кажется я понял, значение переменной задаётся через командную строку, а потом функцией exec выполняется системой. Да, это пиздец уязвимость. Я вчера читал про методы post и get, один из шлёт значение через строку браузера, а второй обращается напрямую к пхп, поможет ли второй метод закрыть уязвимость?
Аноним 02/05/15 Суб 10:52:51 #266 №472037 
>>472034
>задаётся через командную строку

Через адресную строку

Очевиднофикс
Аноним 02/05/15 Суб 10:55:45 #267 №472038 
>>472033

Что сложного то? Подписал в каммент какие значения можно писать и все. И не нужно на каждый пук по методу писать. Я понял принцип этого метода инкапсуляции, но я не понимаю, почему ему нужно беспрекословно следовать не задумываясь о том, целесообразно ли это в данном случае.
Аноним 02/05/15 Суб 11:01:10 #268 №472039 
>>472038
Поясняю: 1) если сломаешь один геттер, сломаешь весь скрипт, 2) выйдет явно большой кусок кода - с ним неудобно работать, 3) если ты добавишь новое поле, тебе придеться редактировать один геттер, а не просто создать новый, не трогая старые. Вот как-то так. Дядьки не зря придумали, что бы ты придерживался его, когда используешь парадигму ООП и все уже набили шишек до тебя.
Аноним 02/05/15 Суб 12:13:08 #269 №472075 
>>471991
>>472033
Инкапсуляция ни при чем равно как и способ получения значения поля. Это и так реализовано, на каждое поле есть свой метод-геттер, если нужно имя я пишу getName(), если нужен телефон - getPhone() и так далее. Задача и проблема в том чтобы иметь способ в зависимости от потребностей получать только те данные которые нужны, не просто выводить, а вообще как бы загружать в объекты которые потом показываются на странице. Вот смотрите на пикчу >>471719
Там один и тот же объект - User встречается 4 раза. Первый - это стенка на которой выводятся вообще все данные пользователя, включая любимые песни и пляски. Остальные три - это вот те мелкие аватарки и имена в разделе friends. Да, они выводятся просто - getName() и все, но при этом они ПРОДОЛЖАЮТ СОДЕРЖАТЬ внутри себя песни и пляски, просто к ним не обращаются. Перфекционисту внутри меня от этого печет - зачем тащить из базы все подряд если оно точно не будет использоваться.
Вот мы и думаем что б тут намутить. Я придумал новый класс minifiedUser у которого есть только getID() и getName(). Это не круто тем что работая с таблицей users мы в разных ситуациях получаем объекты разных классов пусть и похожих по смыслу. ОП придумал все свойства кроме name вынести в специальный хитрый объект profile внутри объекта user. Если его не трогаешь, то внутри ничего и нет, а если запросишь песни и пляски он по-тихому достанет их из базы и выдаст как обычно. Мне это почти нравится, но перфекционизм не сдается - выходит что сущность-User обучается не своему делу - лазить в базу, пусть и через этот прокси-объект, а кроме того залезание в базу будет происходить там где происходит обращение, то есть в html-шаблоне, где согласно mvc-парадигме должны быть только картиночки с котятами.
Не вздумайте страдать такой херней, пацаны.
Аноним 02/05/15 Суб 14:03:39 #270 №472120 
14305646197590.jpg
14305646197611.jpg
14305646197612.png
Аноны, извините если вопрос немного не по теме. Заметил что мне очень нравится минимализм и в веб-дизайне и вообще, в основном конечно минимализм можно встретить на западных сайтах, мне очень сильно захотело научится рисовать в таком стиле что бы делать что то вроде пикрелейтед. На первый взгляд может показаться что это не так сложно, но как по мне так уметь рисовать куда сложнее чем во многих других стилях. Поясните, как можно научится так рисовать? Есть ли какие-нибудь видеокурсы по минимализм в дизайне? Кто то рисует что-нибудь подобно?
Аноним 02/05/15 Суб 14:23:04 #271 №472131 
>>472120
Вот это минимализм http://www.stroustrup.com/, а на твоих пикчах хипстота какая-то.
Аноним 02/05/15 Суб 14:27:12 #272 №472135 
Посоветуйте статейку грамотную и свежую по настройке прав доступа на сервере.
Аноним 02/05/15 Суб 14:35:00 #273 №472140 
>>472131
Ну такой минимализм как здесь, я научился ещё делать когда впервые попробовал ХТМЛ. А как делать тогда хипстоту которая на моих пикчах?
Аноним 02/05/15 Суб 14:53:55 #274 №472155 
Аноны, у меня мало времени, так что всем ответить не успею.

>>471917

Потомок может вызывать методы родителя и обращаться к его полям, если они помечены как protected или public (не private).

class B extends A {
public function doDomething()
{
// взываем методы родителя
$this->callSomething1( );
$a = $this->callSomething2(1, 2,3);
$this->someField = 1;

// вызываем одноименный метод родителя
$x = parent::doSomething( );
}
}

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

>>471991

Спасибо, но это не совсем то.

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

> пишем что-нибудь типа this->getProfile('profile') и он выводит то,
Если функция что-то выводит, то она должна называться не get а print Profile иначе будет путаница. название функции должно отражать что она делает.

Также, вместо строк вроде 'profile' надо использовать константы, например PRINT_PROFILE_SMALL, PRINT_PROFILE_FULL. Ты получишь при этом понятность кода, защиту от опечаток, автодополнение в IDE.

>>472029

Функция exec выполняет переданную ей команду точно так же как если бы ты набрал ее в командной строке (что такое командная строка: https://gist.github.com/codedokode/10539568 ). Команда в твоем случае формируется с использованием полученных от пользователя данных. Следовательно, хитро подставив туда нужные данные мы можем выполнить ту команду которая нам нужна. «Команда» в данном случае значит любая программа, в том числе мы можем запустить программу скачивающую троян и запускающую его.

Ну например, у тебя команда формируется так:

echo $text > COM9

Где $text приходит от пользователя. Что будет если мы передадим в качестве $text

hello | notepad.exe (попробуй вписать это в форму и отправить ее)

Получится команда

echo hello | notepad.exe > COM9

Эта команда запустит (попробует запустить) блокнот. Разумеется мы можем запустить не только блокнот, а например скрипт на VB или скачать любой exe файл командой ftp и запустить его. То есть злоумышленник может выполнить любую команду на твоем компьютере и сделать с ним что угодно.

Я проверил у себя — блокнот запускается.

exec() очень опасная штука. Ты должен 10 раз подумать прежде чем ее использовать. Использовать exec с данными от пользователя — это то же самое что пустить злоумышленника к своему компьютеру и разрешить нажимать любые кнопки.

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

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

А, что с этим делать? Сделай тщательную проверку переменной $text чтобы передать можно было только определенные значения, например 0 или 1, а все остальные значения бы отвергались.
Аноним 02/05/15 Суб 15:06:33 #275 №472163 
>>472031

В Симфони 2 много полезного, шаблонизатор Twig, хороший роутер, Doctrine 2. Но начинать лучше с фреймворка попроще вроде Yii2. Если хочешь у нас есть огромное задание (в первом посте) на этот фреймворк, которое ты можешь начать делать, а я буду проверять код и давать советы.

> Да, кстати, что еще подскажите по-поводу ORM? Есть ли у
php какие-то годные?
Doctrine 2 которая может использоваться отдельно, а также входит в Симфони 2. В Yii2 тоже есть средство для загрузки данных из БД под названием ActiveRecord.

>>472033

У анона речь о другом по моему.

>>472034

Данные как в GET так и в POST приходят от пользователя и он может передать что угодно. То что они не видны в адресной строке ничего не значит так как хакер будет пользоваться не браузером, а программой которая позволяет передать что угодно. Из твоего сообщения я вижу что ты не понимаешь протокол HTTP и как работает браузер.

Браузер просто соединяется с сервером (в твоем случае Апач) и послыает ему запрос по протоколу HTTP (протокол это что-то вроде языка для общения программ между собой, там есть свои команды). Разумеется хакер может соединиться с сервером и без браузера, напрямую, и послать запрос любого вида с любыми данными. Он может положить в POST и GET (а также в COOKIE, SERVER и другие глобальные переменные) любые данные.

>>472038

По моему ты не понял о чем речь. То, что ты предлагаешь не лучшая идея, так как тут есть 2 варианта:

— мы не проверяем при обращении загружали ли мы это поле из базы или нет — 100% баг

— мы проверяем и выбрасываем исключение при обращении к незагруженному полю — по мере развития программы эти исключения будут вылетать постоянно, так как у нас в программе получаются «полноценные» и «неполноценные» объекты, почти неотличимые друг от друга.

А мы хотим чтобы все было единообразно. Если функция printUserNameAndAge принимает на вход объект User и допустим пишет его имя и возраст — мы хотим чтобы она работала с абсолютно любым объектом класса User независимо от того какие поля мы в него загрузили. Это реализуется через прокси-объекты с ленивой загрузкой как вариант.

> Я понял принцип этого метода инкапсуляции, но я не понимаю, почему ему нужно беспрекословно следовать
Чтобы код был надежным, не пропускал ошибки не замеченными, чтобы объекты не позволяли себя неправильно использовать. В конечном итоге все это вместе экономит время на понимание кода новичком и на отладку (меньше времени на поиск ошибок, меньше времени на исправление).
Аноним 02/05/15 Суб 15:34:37 #276 №472182 
>>472163
Я наверное с Yii2 и начну, спасибо. Вообще - да, наверное возьмусь за него.

Мне ActiveRecord очень не нравки, вполне можно к Yii2 прикрутить Doctrine 2, значит все окей.
Аноним 02/05/15 Суб 15:35:11 #277 №472183 
>>472039
>>472038

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

Ну и инкапсуляция нужна конечно. Чем больше приложение тем больше она там нужна.

>>472075

Можно я еще попродвигаю свою идею?

> Вот смотрите на пикчу
Забыл пикчу

> Там один и тот же объект - User встречается 4 раза.
Что насчет идеи про разделение пользователя на основные данные и дополнительные в объекте Profile? Мне кажется тебе как раз бы подошло, тебе бы почти везде нужен был бы только сам User без Profile.

> Да, они выводятся просто - getName() и все, но при этом они ПРОДОЛЖАЮТ СОДЕРЖАТЬ внутри себя песни и пляски, просто к ним не обращаются. Перфекционисту внутри меня от этого печет - зачем тащить из базы все подряд если оно точно не будет использоваться.
Я и предлагаю вынести все лишние поля в Profile спрятанный за прокси, и также вынести другие связанные сущности из других таблиц (например посты на стенке тоже спрятать за прокси и по умолчанию не грузить).

То есть мы разбиваем данные на отдельные объекты и при вызове маппера определяем какие сущности грузятся сразу жадно, какие лениво. Прокси позволяет делать это прозрачно для кода.

Ну например мы грузим User сразу, а Profile, PostsCollection, FriendsCollection, SongsCollection лениво.

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

Ну и если надо то Profile можно еще разбить, хотя я совневаюсь что есть смысл.

Кстати, было бы круто если в доктрине появилась возможность так разбивать объекты. Там лениво можно подгружать только сущности из других таблиц и нельзя (вроде бы нельзя, не уверен, надо проверить, там что-то похожее было) одну таблицу замапить на несколько классов.

> Мне это почти нравится, но перфекционизм не сдается - выходит что сущность-User обучается не своему делу - лазить в базу, пусть и через этот прокси-объект,
Тут нет такой проблемы так как User не знает откуда прокси берет данные. Например мы можем заложить в прокси ссылку на маппер, а можем сразу заложить данные при жадной загрузке. А может он их как-нибудь из кеша грузит. Прокси создается и внедряется в юзера внутри маппера и только маппер знает что в нем содержится и источник данных. User этого не знает, единственное что он знает что надо вызвать getValue или setValue для доступа к этим данным.

То есть прокси это что-то вроде коробки которую надо открыть чтобы полуичть данные.

Прокси приудмал не я, они как раз в доктрине и других ORM используются.

> а кроме того залезание в базу будет происходить там где происходит обращение, то есть в html-шаблоне,
Это верно, потому мы чуть выгибаем парадигму MVC и говорим что шаблон не должен явно лезть в базу, он должен выводить те данные что ему передали. А если при открытии волшебного ящика он достает значения из базы то это ок.

То есть в шаблоне

$mapper->getUser это не ок
$user->getName это ок

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

При этом идея MVC в разделении (вообще, многие проблемы в программировании решаются принципом разделяй и властвуй) кода который работает с базой и который выводит данные. Разделение есть? Есть, маппер работает с базой, шаблон выводит данные.

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

— у нас нет дублирования нескольких объектов для 1 сущности
— допустим вчера функции были нужны поля A, B, C из класса User, а сегодня D, E, F. Функция будет продолжать работать как ни в чем не бывало, разве что может быть вызывая дополнительные запросы в базу. Но это лучше чем вернуть неправильные данные или упасть с исключением что поля не загружены, верно?
— можно поменять ленивую загрузку на жадную, не трогая ни одной строчки кода, кроме вызова маппера. Ни одной строчки! Мы можем играть с оптимизациями как хотим, не меняя код. Если какой-то подход не позволяет легко играть с оптимизацией то скорее всего мы и не будем этим заниматься, так как некогда.
— теоретически мы бы могли даже сделать автоматическое определение что надо загружать лениво,а что жадно. Запускаем программу 1000 раз (при этом записываем число и типы запросов) и смотрим к каким скрытым за прокси сущностям идет обращение, те которые нужны более чем в 80% случаев (или те которые генерируют больше N запросов в базу) грузим в следующий раз жадно. Вот мы и получили автоматический оптимизатор кода. Разве это не круто? Кстати, я про такие пока не слышал.

Ну и по сути это развитие твоей идеи про miniUser. В ней мне не понравилось то, что мы можем получить 2 объекта (User и MiniUser) ссылающихся на 1 пользователя и я просто исправил этот недостаток.
Аноним 02/05/15 Суб 15:42:34 #278 №472187 
>>472075

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

>>472120

Ищи туториалы по рисованию иллюстраций (это вроде называется иллюстрации, а не дизайн) например по таким словам:

minimalist illustration
how to draw minimalist illustration

>>472182

> вполне можно к Yii2 прикрутить Doctrine 2
Это не лучшая идея так как он там не родной, разные полезные плагины рассчитаны именно на AR. То есть ты либо останешься без плагинов и расширений, либо тебе придется написать слой абстракции, маскирующий твои модели под AR.
Аноним 02/05/15 Суб 15:48:17 #279 №472190 
>>472075

C User и MiniUser еще такая проблема: что должны возвращать методы? Допустим у нас есть метод получить автора поста:

$pos->getAuthor()

Что он вернет? User? MiniUser? нам надо делать 2 метода:

$post->getAuthorMini()
$post->getAuthorFull()

И так для каждой связи, каждого метода который возвращает пользователя. Либо же нам надо сделать конвертор который превращает один объект в другой. То есть если ты перфекционист то должен интуитивно понимать что 2 объекта для одной сущности это плохо. Такие вещи должны делаться через оборачивание одного объекта в другой (User содержит внутри MiniUser или наоборот), а не через дублирование данных.

ОП 02/05/15 Суб 16:45:51 #280 №472226 
Я тут решил побаловаться с сайтом speedtest и мне пришла в голову мысль. Как вы наверно знаете, у многих провайдеров есть такая штука, как «буст» скорости: если у тебя допустим тариф на 10 или там 25 мбит (что по моему опыту не имеет разницы), и ты пытаешься что-то скачать то на какое-то небольшое время тебе дается повышенная скорость, а потом падает до нормальной (это хорошо видно например при скачивании популярного торрента). Ну то есть небольшой файлик скачается быстрее за счет этого. И люди которые не качают данные постоянно, а серфят страницы не спеша, получают более быстрый доступ. Какие хорошие и заботливые люди эти провайдеры, можно подумать!

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

А еще я подумал, если есть какой-то способ определять сервера speedtest то можно до них выделить более широкий канал. Или как-то обманывать этот тест скармливая ему данные из локального источника на большой скорости. У меня ощущение что мой провайдер что-то такое делает, потому что там почти везде (кроме далеких городов с большим пингом вроде Токио или СФ) выдается цифра под 100 мбит.

Такие дела.
Аноним 02/05/15 Суб 16:49:18 #281 №472229 
>>472226

Ну так если они сразу двух зайцев убивают, то не похуй ли?
Аноним 02/05/15 Суб 16:57:12 #282 №472232 
>>472229

Ну я то думал, это только ради пользователей, а не тестов делается!

Справедливости ради, эта скорость выше определенного предела все равно ни на что не влияет, так как сайт не может отдавать контент быстрее определенного предела, к тому же самая популярная соцсеть в России у нас подсоединена напрямую без ограничений по скорости.
Аноним 02/05/15 Суб 17:09:37 #283 №472240 
>>472232
> самая популярная соцсеть в России у нас подсоединена напрямую без ограничений по скорости

шта?
Аноним 02/05/15 Суб 17:23:19 #284 №472246 
>>472240

Крупный провайдер может напрямую подключиться к вконтакте, соответственно трафик там по моему бесплатный и он может его предоставлять без ограничений скорости:

https://vk.com/help.php?page=peering
http://vk.com/dataix_peering

Аналогично у яндекса что-то было.

Ну а гугл и ютуб вообще свои сервера кеширующие ставит к провайдеру. У меня иногда некоторые видео качаются с сервера из локальной сети.
Аноним 02/05/15 Суб 17:36:13 #285 №472256 
>>472226
Ебать ты мамкин конспиролог
sageАноним 02/05/15 Суб 18:53:27 #286 №472299 
>>468317
Ебать, тред ведет ещё оп-долбоеб с синдромом вахтера? Сажи на хуй, сажи блядь.
Аноним 02/05/15 Суб 20:02:49 #287 №472322 
14305861698600.png
>>472155
>Сделай тщательную проверку переменной $text чтобы передать можно было только определенные значения, например 0 или 1, а все остальные значения бы отвергались.

Так норм будет?
Аноним 02/05/15 Суб 20:23:14 #288 №472331 
Аноны поясните по поводу вордпресс, вывожу некоторые данные из таблицы (таблица не постс) при помощи такого метода:

$table_item = $wpdb->prefix.bulletin;
$posts = $wpdb->get_results("SELECT*FROM $table_item");
foreach ($posts as $post) {
echo $post->title;
echo $post->description;
....
}

как мне сделать ссылку $post->title; на станицу с единичным постом, the_permalink() не помогает, стандартным образом в таком случае

<a href="single.php?id=<?= $post->id;?>"> echo $post->title;</a>

Тоже не получается, что делать? Я так понял стандартный цикл вордпресс работает только с таблицей постс?
Аноним 02/05/15 Суб 21:19:56 #289 №472353 
14305907967770.png
>>472183
>Забыл пикчу
Не забыл, я там прост номер поста дал в котором она была. Вот посвежей.
В общем, мыслей всяких много, пишу код как стахановец, поэтому вкратце:
1. вариант с мини-юзерами сделал, все работает, подводных камней все еще не вижу.
2. вариант с Profile и ленивой загрузкой... сложновато, но я не сдаюсь. Кое-что написалось, а запара вот где. Пойдем от обратного. Мы где-то во вью впервые вызвали $user->profile->getCity(). Город у нас изначально не загружен. Объект Profile смотрит во внутреннюю переменную $isDataLoaded (по умолчанию false) понимает что он пустой и запускает внутренний метод loadDataFromDb() который призван достать вообще все данные(не только город) и полностью заполнить профиль, после чего поменять $isDataLoaded на true для будущих обращений и вернуть наконец город. А вот внутри этого метода, добывающего данные, начинается какое-то хождение по кругу, ведь методы маппера возвращают экземпляры User-а, а нам нужно что-то типа ассоциативного массива который можно раскидать по полям Профайла. То есть нам там класс DB больше помог бы, а не маппер. Либо мапперу надо добавить метод getDataForProfile(), но это ведь уже не маппер получится
3. Есть еще другие идеи, но хочу добить твою.
Аноним 02/05/15 Суб 21:45:32 #290 №472366 
>>472322

is_numeric это недостаточно хорошо. is_numeric пропустит странные штуки вроде 2.3e-04 и может быть что-то еще.

Сделай нормальную проверку, например регулярным выражением что это именно число от 0 до 255 (или до 999 если это проще).

Тут лучше быть параноиком.

Хотя, нет. Я перечитал твой код и тут опять дыра. Код опять неправильный из-за неправильного использования &

Сейчас ты проверяешь непонятно что, я думаю что если в $va1 передать 0, а в остальных переменных команду то она пройдет.

Я же писал выше что ты сначала должен иучить PHP:

is_numeric ($va1 & $va2)

сначала преобразует значения из va1/2 к числу и сделает над ними побитовое И. Скорее всего получится число 0, которое вполне устроит функцию is_numeric и таким образом мы можем передать что угодно.

В любом случае операция & вернет число и это значит что любые значения va1-3 пройдут проверку (ты ведь не тестировал свой код и не пробовал подставить туда что-то левое, верно?)

Такие опасные функции как exec должны использовать люди, понимающие, что они делают, а не копипастящие куски кода из инернета. Безопасный код так не пишется.

Также, если ты выдал заголовок Location то браузер не отобразит текст ошибки.
Аноним 02/05/15 Суб 21:53:00 #291 №472371 
>>472331

Попробуй изучить какие есть функции для получения ссылки Не на текущий, а на произвольный пост. То есть тебе нужна функция вида

get_something_link($post)

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

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

>>472353
> Мы где-то во вью впервые вызвали $user->profile->getCity()
Должно быть $user->getProfile()->get...

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

$this->profile = $mapper->loadProfileForUser(...);
$this->city = $mapper->loadCityForSomething(...);

ну и лучше это сделать не явно вписывая код загрузки и заполнения в User, а используя прокси, которые создаются в маппере. Маппер лучше знает какие данные есть, а какие надо загрузить потом. А у тебя User с базой работает, а это не соответствует идеям data mapper и код делает запутаннее с большей вероятностью сломаться.
Аноним 02/05/15 Суб 23:35:00 #292 №472456 
14305989000700.png
>>472371
>ну и лучше это сделать не явно вписывая код загрузки и заполнения в User, а используя прокси, которые создаются в маппере.
Так он не в User вписан, а в Profile, я думал Profile это и есть прокси. Ну вот что-то такое
//Создание в маппере
$user = new User;
$user ->setName('Alex'); //обычное поле
$profile = new Profile;
$user ->setProfile($profile); //пустой профайл
//применение во view
<span>Phone: <?=$user->getProfile()->phone; ?></span>
<span>Skype: <?=$user->getProfile()->skype; ?></span>
(магический гет чтоб не писать множество getSomething)

Аноним 03/05/15 Вск 00:14:07 #293 №472473 
>>472456

Прокси это отдельный объект который может либо содержать внутри модель, либо содержать ссылку на маппер и загружать модель при первом обращении.

Прокси создается и вставляется в User в маппере. Он нужен чтобы модель (User) не думала откуда брать данные. Соответственно код в User будет выглядеть так:

publuc finction getProfile()
{
return $this->profileProxy->getValue( );
}

Его лучше сделать отдельным классом чтобы в модель не засовывать логику ленивой загрузки (которой там не место). Более того, моделей много и тебе придется копипастить эту логику, что плохо.
Аноним 03/05/15 Вск 00:15:15 #294 №472474 
>>472456

Вообще ты можешь вместо getProfile() как метода писать

$user->profile->skype

Если твой магический _ _ get умеет сам находить и вызывать геттер.
Аноним 03/05/15 Вск 00:27:40 #295 №472478 
>>472456

И еще смотри какие у тебя недостатки:

— в модель вписана логика ленивой загрузки, которой там не место. Модель должна знать, что данные загружаются лениво и что любое поле может отсутствовать и это значит что тебе придется любой доступ к полю заворачивать в if ($dataIsLoaded) либо надеяться на магический геттер.

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

— ты создаешь маппер внутри модели что вообще неправильно. Где этот маппер возьмет ссылку на соединение с БД например? И сколько у тебя в итоге мапперов будет в программе? Это верный путь к бардаку. Почитай-ка урок (он не очень простой, но суть в том, что ты не должен создавать маппер внутри модели, а должен использовать ранее созданный экземпляр) https://gist.github.com/codedokode/e1d31a31b37d5f635057

Ну и вспомни аналогию с краном и контейнером. Маппер создает объекты модели, а не наоборот.

Соответственно реализация с прокси делается примерно так:

— либо (что проще) маппер при создании User засовывает в него прокси для Profile, но сам Profile пока не создает. Так как маппер создает прокси, то он может передать ему ссылку на себя и нужные для ленивой загрузки параметры

Этот вариант требует кооперации со стороны User: модель должна знать что профиль хранится внутри прокси и должна уметь вызывать у него getValue()

— либо (что сложнее) прокси может быть наследником Profile (ProfileProxy), перехватывать обращение к любому методу или полю и перед вызовом метода у Profile загружать данные из БД. Создается такой прокси тоже в маппере. Преимущество в том, что от самой модели Profile не требуется поддержки и ей не надо знать откуда берутся данные (в предыдущем способе модель содержит прокси внутри и знает о его существовании, тут нет). Минус в том что это очень сложно, так как надо генерировать прокси-классы наследники для каждой модели. Доктрина так делает, но это сложно в реализации.
Аноним 03/05/15 Вск 00:30:42 #296 №472480 
>>472456

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

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

Аноним 03/05/15 Вск 00:48:55 #297 №472483 
Вот думаю, что задания на тесты большое очень и мне лень с ним очень долго сидеть, пожалуй я сделаю uppu.ru на yii2.
Аноним 03/05/15 Вск 00:51:36 #298 №472484 
>>472483

Может лучше сделать только часть задания, например возможность создавать и проходить тесты без авторизации и регистрации? Так да, оно большое.
Аноним 03/05/15 Вск 00:58:20 #299 №472488 
>>472484
Может, но думаю, что все-таки начну с сайта с файликами потому, что хочу уметь с ними работать, к тому же, туда есть пара идей в будущеем, как улучшить
Аноним 03/05/15 Вск 14:21:34 #300 №472656 
Как перестать заниматься хуетой и начать заниматься делом?
Спасибо.
Аноним 03/05/15 Вск 14:28:22 #301 №472661 
>>472656
Никак. Оставайся в говне.
Аноним 03/05/15 Вск 14:31:07 #302 №472662 
>>472661
((9
Аноним 03/05/15 Вск 14:32:58 #303 №472664 
14306527783230.jpg
>>472662
Аноним 03/05/15 Вск 16:06:14 #304 №472709 
14306583744550.png
>>472473
>>472474
>>472478
Анон, кажется все получилось.
1. Загрузили жадно: профиль заполнен, маппер не передается, isDataLoaded = правда.
2. Загрузили лениво: профиль пуст, но зато есть маппер, isDataLoaded = неправда.
3. Запросили телефон: профиль заполнен, isDataLoaded = правда, обращайся дальше к чему хочешь. маппер, наверное, и удалить можно.
Крутой челендж для меня.
ГОСПОДИ ИИСУСЕ Я КОМАНДУЮ ПАРАДОМ
Аноним 03/05/15 Вск 17:06:46 #305 №472737 
Учу ПХП довольно немного, хоть и впервые попробовал примерно месяцев 7 назад, были перерывы. Сейчас вроде бы могу написать простенький сайт со стандартным функционалом, хочется написать какой-нибудь интересный сайт, ну что бы не стандартный блог какой-нибудь, а что то интересное вроде сбора какой-нибудь локальной интернет статистики или какого-нибудь другого сайта с несложным но нестандартным функционалом. Тут наверняка есть начинающие вроде меня, может у кого-то есть идеи? Давайте попробуем реализовать их.
Аноним 03/05/15 Вск 17:32:34 #306 №472752 
>>472709

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

Допустим мы сделаем в классе Profile (который у тебя называется Proxy) метод hasSkype:

public function hasSkype()
{
return !empty($this->skype);
}

При такой реализации обращение к этому методу изнутри не вызовет загрузки данных и выдаст неверный результат:

var_dump($user->profile->hasSkype( )); // упс

В твоей реализации единственный способ избежать бага это дописать явно вызов кода ленивой загрузки:

public function hasSkype()
{
$this->loadDataIfNotLoaded( );
return !empty($this->skype);
}

И такой код придется писать в начале каждого метода. Потому что в твеой реализации модель должна помнить про то что поля могут остутсововать и делать проверку. Это неудобно и засоряет код.

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

class ProfileProxy extends Profile
{
private $isDataLoaded = false;
private function loadDataIfNotLoaded() { .... }

// переопределяем метод чтобы перехватить обращение к нему
public function hasSkype()
{
$this->loadDataIfNotLoaded( );
return parent::hasSkype( ); // теперь спокойно вызываем исходный метод
}
}

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

Потому я тебе предлагаю другой подход, разделить отдельно класс Profile (в котором хранятся данные) и класс Proxy (который загружает из базы объект Profile при первом обращении).

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

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

Ну и я чувствую что мы такими темпами через месяц сделаем свой клон доктрины.
Аноним 03/05/15 Вск 17:45:27 #307 №472761 
>>472737

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

Ну и если тебе надо еще, у меня есть готовые идеи (подробного описания идей нет):

— BookHub, сервис для желающих обмениваться книгами
— TweetAlarm, одностраничная напоминалка которая в указанный день напомнит через твиттер что ты должен сделать
— music tv — выбираешь интересующий тебя жанр или канал или исполнителя, и она играет музыку (видео с ютуба или другого источника). Система обучается и подстраивается под твои вкусы, если ты например пропускаешь треки или наоборот плюсуешь. Можно создавать и публиковать плейлисты с минимальными затратами усилий, например «сохрани все что я сегодня слушал и не пропускал».
— Редактор для совместного написания кода (wtf?)
— living pictures — делает из фото анимацию, например добавляя какой-нибудь эффект поверх или что-нибудь еще. Ты скажешь что это никому не нужно а я скажу что инстаграм продался за огромные деньги, а ведь в нем нет анимации, а у нас будет.
— игра в ассоциации (не помню что это значит)
— torrent monitor — добавляешь сериал, который тебя интересует, выбираешь качество/тип/релизера и он автоматически отслеживает появление новых серий и выводит на одной страничке
— heapp — сервис, позволяющий создать свою «свалку» заметок, файлов, ссылок (клон evernote?)
— Сервис где можно писать разные мелодии, выкладывать их, смешивать, форкать и переделывать (то есть что-то вроде гитхаба для музыки)

Аноним 03/05/15 Вск 18:02:47 #308 №472770 
>>468317
Блядь у меня бомбит. Пишел на первую свою работу, ща думаю охуенно покодю, применю знания, наберусь нового, короче заебца.
И вот выясняется, главный кодер в конторе - хейтер ооп, функциональщик. Ооп ненужно, то ненужно, Се не нужно. Нужно создать таблицу? Нормализация не нужна, ибо "абстрактная хуйня избыточная, в нашем конкретном случае конкретно для этой таблицы достаточно 2й формы или даже 1". И такое повсюду. Бляд у меня люто бомбит от этого а спорить не могу, ибо нуб и мнение свое не смогу перед авторитетом отстоять.
Задвигал мне этот чувак, что это слишком "жирно" - позволять себе кодить идеально или даже оченьорошо
Мне валить срочно или такое норм?
Аноним 03/05/15 Вск 18:05:56 #309 №472771 
>>472770
Собстна нахуя я пыхтел в универе, если все оказывается ненужным?
Аноним 03/05/15 Вск 18:08:37 #310 №472772 
>>472770
Иди в аутсорсинг каким-нибудь джавистом. Там всё строится на распиле денег на разработку за счёт шизофреников, упрямо дрочащих на инструменты и методологии, позволяющие решать задачу в 1000 раз дольше, чем можно было.
Аноним 03/05/15 Вск 18:11:07 #311 №472774 
>>472772
Но как же душа? Чувство прекрасного? Моральное удовлетворение в конце концов?
Неприятно от опознавания того факта что проделана работа и проделана некачественно и можно было бы лучше. Разве не так?
Аноним 03/05/15 Вск 18:11:13 #312 №472775 
>>472771

Ну насколько я понимаю, если мелкие сайтики клепать в промышленных массштабах, то ООП тебя только тормозить будет и по сути нахуй не нужно. Понятное дело, что если проект крупный и будет поддерживаться множеством людей, то без ООП никуда.
Аноним 03/05/15 Вск 18:15:31 #313 №472778 
>>472774

Люди разные бывают и запросы у клиентов тоже разные. Есть те, которые по сто лет вылизывают код, а есть те, которым важнее КПД и они могут сделать работающий ( пусть и не идеально) сайт в разы быстрее. А если особой разницы нет, то многие клиенты попросту не будут ждать, пока первая категория там свой код вылижет.

Если ты все-таки к первой категории принадлежишь, то можешь поискать другую контору, где будут работать люди с похожими взглядами, т.к. очевидно, что текущий главный кодер явно не из них.
Аноним 03/05/15 Вск 18:24:29 #314 №472782 
>>472774
Психически здоровый человек не может любить программирование, увлекаться им, получать какое-то там эстетическое удовольствие от кода. Сами эти словосочетания некорректны, "не тайпчекаются". В программировании нет самоценности, предназначение кода лишь в том, чтобы решать какую-то внешнюю задачу, достигать какие-то внешние цели. Это чисто-инфраструктурная деятельность и рационально-мыслящий человек будет искать любые пути, чтобы минимизировать её необходимость для достижения своих целей - будь то домашняя автоматизация или работа ради денег.
Аноним 03/05/15 Вск 18:38:05 #315 №472786 
>>472770

Ну насчет ООП не нужен, это как минимум неправильно. ООП не вчера появился, он стал модным в конце 80-х и большинство проектов с тех пор пишется с его использованием (в мире PHP раньше действительно с ООП было плохо, но если брать новые проекты то они тоже все на ООП). ООП позволяет сделать код более надежным и понятным, разбивая его на изолированные классы.

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

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

ООП это часть языка и отказываться от него это то же самое что например отказываться от циклов или функций — а давайте все писать сплошной стеной кода, чтобы не тратить времени? Это называется write only код: код который потом никто не сможет прочесть.

Такой подход может сработать если вы делаете простые однотипные сайтики, но мое мнение:

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

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

Вы еще фреймворки и гит небось не используете?

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

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

> хейтер ооп, функциональщик.
Функциональщик это хаскеллист. А это процедурщик.

>>472772

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

> позволяющие решать задачу в 1000 раз дольше, чем можно было.
Бизнес вряд ли захотел бы платить в 1000 раз больше если можно заплатить в 1000 раз меньше. Может быть ты придешь и сделаешь ту же работу например в сто раз быстрее чем куча бездельников с архитекторами, коде интегрейшен, системами контроля версий, объектно-реляционными мапперами, многослойной архитектурой и прочим ненужным мусором который придумывают неучи-теоретики вроде Фаулера?
Аноним 03/05/15 Вск 18:41:14 #316 №472788 
14306676743670.png
> Бизнес вряд ли захотел бы платить в 1000 раз больше если можно заплатить в 1000 раз меньше
Ты, я смотрю, дохуя в бизнесе понимаешь.
Аноним 03/05/15 Вск 18:46:18 #317 №472792 
14306679783830.png
14306679783841.png
14306679783842.png
>>472752
>Потому я тебе предлагаю другой подход, разделить отдельно класс Profile (в котором хранятся данные) и класс Proxy (который загружает из базы объект Profile при первом обращении).
А у меня все так и есть. Может по вар_дампу не видно. У юзера в поле $profile хранится экземпляр Proxy, который при обращении возвращает экземпляр Profile, как-то так. И у маппера есть флажок. Вот. Еще не вычитывал, может где-то что получше можно сделать. Но, пожалуй, это уже бета версия, а то так до ассемблера можно дойти.
И кстати, ты говорил про перехват обращений к свойствам - это внутри __get() легко можно сделать, правда довольно криво:
__get($name) {
$method_name='get'.ucfirst($name);
if (method_exists($this, $method_name)) {
return $this->{$method_name}();
} else {
return $this->{$name};
}
Ну или явно перечислить
if ($name=='skype') {
return $this->getSkype();
} else {
return $this->{$name};
}
Правда если перехватывать несколько, то нужен будет свич, но то уже такое.
Аноним 03/05/15 Вск 18:49:30 #318 №472794 
>>472774

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

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

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

>>472775

Ты неправильно понимаешь. Заявления о тормозящем ООП надо сопровождать тестами. Также помни что маленькие сайтики обычно посещает 100 человек в день и тормозить там особо нечему.

Я работал над хайлоад сайтом и код там использовал MVC/ООП (без фанатизма и абстракций).

>>472778

Бизнесу выгодно побыстрее, программисту выгодно развивать свой уровень и перейти на более сложную и интересную работу а не клепать всю жизнь примитивные сайты и выслушивать на утренней планерке от менеджера на сколько мы отстаем от графика и на сколько часов нам сегодня придется задежаться. Ты ведь не работал в компаниях которые делают простые сайты на потоке (я тоже не работал, но читал отзывы)? Там обычно низкие зарплаты (ибо с высокой ты не сможешь делать сайт за 3000 рублей, ну сам подумай если час работы стотысячного программиста стоит 100 000 / 168 = 600 рублей, это без налогов и соцвыплат, а ведь для сайта нужна еще верстка, настройка и тд), штрафы во все поля, менеджеры и корпоративные ценности, большая текучка и люди долго не задерживаются.

Аноним 03/05/15 Вск 19:10:02 #319 №472801 
>>472788

> в бизнесе понимаешь.
Те кто создают программные продукты и зарабатывают на них, я думаю, понимают. Майкрософт, Эппл, Гугл, Яндекс и остальные. А ты пытаешься создать впечатление что они ничего не понимают, а ты один умный. Если ты такой умный то почему не создаешь более успешный бизнес который будет делать те же продукты с в 1000 раз меньшими затратами на абстрактных монадах высшего порядка и не выбьешь этих старых неудачников с рынка?

>>472782

Обоснуй

>>472792

Мне кажется лучше сделать немного по-другому. Вынести из прокси создание Profile и простановку свойств в маппер, который этим должен заниматься. То есть:

public function getProfile()
{
if (!$this->isDataLoaded) {
$this->profile = $this->profileMapper->getProfileById($this->profileId);
}
...

А то ты размазываешь логику маппинга данных из БД и создаение объекта Profile между маппером и прокси. Мне кажется прокси должен быть очень тонким и всю работу по загрузке объектов оставить в маппере.

Ну и если сделать метод в маппере то мы можем грузить Profile даже без юзера, не знаю, нужно ли это, но все же.

Также, не очень понятно зачем там метод setProfile который принимает массив если он может принимать готовый объект Profile (а создает этот объект пусть маппер).

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

Также я бы сделал у прокси 2 статических конструктора, а обычный сделал приватным. Конструкторы такие:

— создать прокси имея заполненный объект
— создать прокси без объекта, имея его id и ссылку на маппер

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

В маппере, мне кажется вместо $method (который должен принимать константы, а не строки) удобнее сделать массив $greedyLoad который говорит какие сущности надо подгрузить жадно. У тебя ведь в будущем кроме Profile будут еще другие дополнительные сущности связанные с пользоватем, наверно (например, посты, список друзей и тд).

> И кстати, ты говорил про перехват обращений к свойствам - это внутри _ _ get() легко можно сделать, правда довольно криво:
Это вполне нормальный способ, фреймворки так делают. ucfirst можно не писать так как функции регистронезависимы.

> Ну или явно перечислить
Лучше наверно не перечислять, там будет при 30 полях 30 вариантов.
Аноним 03/05/15 Вск 19:11:53 #320 №472805 
>>472761
Задания смотрел сделал всё кроме сайта для проведения тестов. Спасибо за идеи, попробую реализовать, хорошо что времени у меня впринципе много, понимаю почти в каждой из них надо уметь неплохо парсить, кстати, какой метод для парсинга посоветуешь? Что лучше использовать?
Аноним 03/05/15 Вск 19:12:57 #321 №472806 
>>472794
>ООП тебя только тормозить будет.

Имелось ввиду, что функциональщиой на мелких проектах лепить быстрее, чем ООП.
Аноним 03/05/15 Вск 19:22:00 #322 №472810 
>>472371
>
>Попробуй изучить какие есть функции для получения ссылки Не на текущий, а на произвольный пост. То есть тебе нужна функция вида
>
>get_something_link($post)
У меня ещё проблема, я не знаю как передать ID на страницу single.php или ID в вордпресс передаётся это автоматически? И на странице single.php достаточно просто написать функцию получения этого самого ИД?
Аноним 03/05/15 Вск 19:22:44 #323 №472811 
>>472805

Парсить (скрейпить)? По моему это почти нигде не нужно, разве что в torrent monitor если у торрент трекера нет API, либо в heapp, остальные приложения либо используют API либо не используют внешние сервисы.

Заниматься скрейпингом довольно тупиковый путь так как он постоянно будет ломаться и требовать подстройки.

> какой метод для парсинга посоветуешь
DOM + XPAth или библиотека для поиска по CSS селекторам вроде phpQuery. какие еще могут быть варианты?

>>472806

А, понял. Мне кажется, это акутально только для программистов плохо знакомых с ООП, так как если ты с ним хорошо знаком то все как-то само собой пишется (а если плохо знаком то быстро научишься). Ну и если ты используешь фреймворк то ООП знать надо в любом случае, а без фрйемворка как раз писать будет дольше и неудобнее.
Аноним 03/05/15 Вск 19:24:07 #324 №472812 
>>472810

Там должна быть функция для получения id текущего поста.

Набираем в гугле

wordpress api get post id

И в первой же ссылке видим ответ.

Аноним 03/05/15 Вск 19:48:43 #325 №472824 
<script src="../assets/libraries/node_modules/angular/angular.min.js"></script>
Почему это может на работать? Путь указан верно 100%. На сервер приходит "GET /assets/libraries/node_modules/angular/angular.min.js".
Аноним 03/05/15 Вск 19:56:12 #326 №472827 
>>472824

Потому что путь резолвится относительно URL самой страницы.

Страница http://example.com/lalala -> получается http://example.com/assets/libraries..
Страница http://example.com/lalala/1/2/3 -> получается http://example.com/lalala/1/2/assets/libraries..

.. значит подняться на 1 уровень выше.

http://htmlbook.ru/samhtml/ssylki/absolyutnye-i-otnositelnye-ssylki


Аноним 03/05/15 Вск 20:38:37 #327 №472854 
Пишу скрипт по регулярным выражениям.
Чтобы поставить любой символ, кроме цифр, который может встречаться сколько угодно раз, а может и не встречаться, пишу так:
/[^0-9]?{1,}/
Это правильно, или знак вопроса надо ставить после {}?
Аноним 03/05/15 Вск 21:01:34 #328 №472864 
>>472854

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

В твоем случае надо писать

([^0-9]?){1,}

Но писать так не надо, а надо чуть подумать.

> может встречаться сколько угодно раз, а может и не встречаться,
Для этого есть символ звездочка, он значит от 0 до бесконечности повторений.

Алсо мануал http://php.net/manual/ru/regexp.reference.repetition.php
Аноним 03/05/15 Вск 21:05:19 #329 №472866 
>>472864
Ну вот так я выполнил задание: http://ideone.com/wbprnC
Сильно криво?
По заданию надо чтоб этот номер можно было вводить хоть как, главное чтобы он совпадал.
Аноним 03/05/15 Вск 23:11:09 #330 №472920 
>>472866

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

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

Для этого давай добавим в программу тесты, чтобы сразу было видно, верно все работает или нет. Сделай 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' // нет +
);
Аноним 03/05/15 Вск 23:38:03 #331 №472944 
14306854833420.jpg
Начал вот изучать по-тутариалу Yii2, знаком с mvc и ооп(читал, ооп применял только пару паттернов, когда писал на java). Так вот, мне не нравиться :c Это довольно уныло его использывать. Есть ли в php области применения, где обходяться без фреймворков и клепания по-шаблонах?(Если, что у меня математическое образования).

Алсо по архитектуре и проектированию бд что почитать, желательно кратко, но насыщенно? С sql знаком
Аноним 04/05/15 Пнд 00:24:19 #332 №472978 
14306882594980.png
14306882594981.png
>>472801
>Вынести из прокси создание Profile и простановку свойств в маппер, который этим должен заниматься.
Переделал
>Мне кажется логичнее вставлять id на этапе создания прокси
Переделал
>Также я бы сделал у прокси 2 статических конструктора
Сделал, вроде все так.
>обычный сделал приватным.
Да он теперь вроде и не нужен
>который должен принимать константы, а не строки
А в чем профит констант? И где их надо объявлять?
>В маппере, мне кажется вместо $method (который должен принимать константы, а не строки) удобнее сделать массив $greedyLoad который говорит какие сущности надо подгрузить жадно. У тебя ведь в будущем кроме Profile будут еще другие дополнительные сущности связанные с пользоватем, наверно (например, посты, список друзей и тд).
Ну а это самое интересное. Вот сижу, думаю. С профайлом вопросов нет, даже если город берется из другой таблицы это ну очень близкое свойство для юзера, как запись в паспорте. А вот список друзей или записи на стенке... Вот смотрю я на сущность User и вижу что она какая-то сильно умная и жирная получается. Вот не помню, у Зандстры кажется где-то читал что первый звоночек о том что пора пилить новый класс - если текущий сильно много знает и умеет. Кроме того, чем толще User тем толще UserMapper, и чтоб уметь лениво грузить друзей, посты и прочее ему придется обучаться лазить едва ли не во все таблицы. И уже сейчас он ворочает юзерами, профайлами, проксями, а потом будет постами, френдлистами еще чем-то. Кроме того, у меня та модель что между контроллером и маппером (кажется ее доменной называют?) она наоборот ничего не делает, а просто возвращает то что ей вернул маппер. Может таки разумнее разнести по разным объектам и в контроллере получать как
$model = new UserHandler; //доменная(?) модель
$data['user'] = $model ->getUser(); //внутри просто вызов юзермаппера
$data['friends'] = $model ->getFriendsList(); //вызов маппера по таблице с отношениями юзеров
$data['wall'] = $model ->getWall(); //вызов маппера по постам
С другой стороны, круто иметь возможность написать $user->getFriendList().
Словом, в очень больших раздумьях я.
Аноним 04/05/15 Пнд 01:10:29 #333 №473000 
>>472944
>Есть ли в php области применения, где обходяться без фреймворков и клепания по-шаблонах?

Нет. Серьёзно.
Аноним 04/05/15 Пнд 02:09:03 #334 №473024 
>>472978

>>Вынести из прокси создание Profile и простановку свойств в маппер, который этим должен заниматься.
> Переделал
Не до конца. Ты простановку свойств из массива почему-то делаешь в прокси. Это во-первых неправильно так как ты не можешь таким образом получить снаружи доступ к приватным свойствам, во-вторых неединообразно. И непонятно почему прокси этим должен заниматься если создание объектов и заполнение свойств задача маппера.

Ну и ты опять гоняешь массивы туда-сюда хотя мог бы передавать объект.

Логично получать объект Profile из маппера:

if (!$this->dataIsLoaded) {
$this->profile = $this->mapper->loadProfile($this->id);
}

> А в чем профит констант?
Профит в том что код понятный и надежный (например не получится сделать опечатку). Со стороками ровно наоборот:

— непонятно что значит строка, к чему относится и какие еще есть варианты строк
— если ты опечатаешься то это не будет обнаружено
— нет автодополнения в IDE

> И где их надо объявлять?
Там, к чему они относятся. Константа в данном случае управляет работой маппера и должна быть объявлена в нем:

Mapper::LOAD_GREEDY

Смотри, насколько нагляднее: видно к чему относится константа, за что отвечает,а заглянув в класс можно увидеть какие еще есть варианты выбора. И как бонус работает автодополнение в IDE.

В моем учебнике эта тема не освещается, но ты должен бы был ее изучить когда изучал ООП. А то ты пишешь ORM а как использовать константы не знаешь.

Константы это конечно не самое идеальное решение, более идеальное это enum (специальный тип данных, который содержит в себе все возможные значения), но в PHP пока их не завезли. В других языках (например C#: https://msdn.microsoft.com/ru-ru/library/sbbt4032.aspx ) это делается так:

— объявляем enum с вариантами:

enum LoadType {
GREEDY = 1,
LAZY = 2
};

— указываем в функции что она принимает только значения из этого энума:

User getUserById(int id, LoadType method) {
...

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

Это конечно лучше чем в PHP, где нет проверки на то что ты передал допустимую константу.

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

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

> Кроме того, у меня та модель что между контроллером и маппером (кажется ее доменной называют?) она наоборот ничего не делает, а просто возвращает то что ей вернул маппер.
Она делает важную вещь, она хранит в себе информацию о пользователе и позволяет ее передавать. И она по мере роста проекта будет много где использоваться, любая функция которой нужна информаия о юзере будет ее принимать на вход. Это чуть ли не основа твоего приложения.

И как без нее? К массивам возвращаться? Это верный путь в ад. Тебе в любом случае нужно что-то чтобы хранить данные пользователя.

> а потом будет постами, френдлистами еще чем-то.
Нужны отдельные объекты КоллекцияПостов (содержит Посты) и СписокДрузей (содержит Пользователей), а юзер будет содержать их в себе, спрятанные за прокси. Каждая за своим прокси конечно.

> Может таки разумнее разнести по разным объектам и в контроллере получать как
> $model = new UserHandler; //доменная(?) модель
А что значит UserHandler? Слово Handler ничего не значит, получается это то же самое что User? Я не очень понимаю. В твоем коде по моему тогда проще напрямую обращаться к мапперам:

$user = $userMapper->getUserById(..);
$firends = $firendsMapper->getFriendsForUserId(..);

То есть я не понимаю зачем этот «UserHandler» вообще нужен.

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

Код конечно сложнее, но я же предупреждал что писать свой ORM это боль и унижение.

Аноним 04/05/15 Пнд 02:40:40 #335 №473044 
>>472944

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

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

Что тебе было бы интересно делать? Напиши, а я скажу какие языки/платформы для этого используются.

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

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

Аноним 04/05/15 Пнд 05:53:57 #336 №473079 
Антон, есть задача:

a - количество юзеров из одной локации
b - колчество юзеров из другой локации
c - количество юзеров из третьей локации
n - количество юзеров, которое может обработать сервер.

n всегда меньше a + b + c
надо найти количество конфигураций, в которых сервер может обработать максимальное количество юзеров, т.е. в которых выполняется a + b + c = n

например, a = 1, b = 1, c = 1, n = 2
a b c
1 1 0 = 2
1 0 1 = 2
0 1 1 = 2
ответ: 3 варианта
второй пример: a = 2, b = 2, c = 2, n = 2
a b c
1 1 0 = 2
1 0 1 = 2
0 1 1 = 2
2 0 0 = 2
0 2 0 = 2
0 0 2 = 2
Ответ: 6 вариантов

Понятно, что нужно делать итерации, но я никак не могу вспомнить как решается в математике подобная задача и стакнулся.
Аноним 04/05/15 Пнд 08:54:35 #337 №473101 
14307188750170.jpg
>>473044
>>Как без фреймворков? С нуля писать? А в чем выгода делать дольше то, что можно сделать быстро?
Нет, это я прекрасно понимаю. Просто спрашиваю может есть вещи, где фреймворки не подойдут, допустим из-за избыточности?
>>Что тебе было бы интересно делать? Напиши, а я скажу какие языки/платформы для этого используются.
Не знаю, хех. Ну как ты сказал выше строить красивые абстрактные конструкции
>>Если ты знаешь про нормализацию, отношения между таблицами, внешние ключи, этого тебе хватит для большинства случаев.
Ну ладно. Сам может что интересное найду
Аноним 04/05/15 Пнд 09:01:01 #338 №473104 
нужно проверить html тэг на отсутствие класса, соответственно если этого класса у тэга нет, то заменить кое-какие ссылки. как это сделать? также нужно чтобы условие по замене ссылок срабатывало только если юзер сидит с мобилы(ipad, iphone, и прочие) либо просто если ширина экрана меньше скажем 480px. как это сделать?
в гугл ходил, как-то не удалоось
Аноним 04/05/15 Пнд 09:27:51 #339 №473111 
>>473024
>Лучше для этого сделать еще мапперы, маппер для городов, для друзей и тд, для каждой отдельной таблицы свой. А не сваливать работу со всеми таблицами в один
Они-то у меня уже заготовлены, только если я связанный объект-профайл получаю лефт джоинами по разным таблицам внутри getUserById() маппера UserMapper то получается что и друзей со стенками надо там же и также создавать, а иначе как? Мапперы внутри маппера? Не круто и не решает проблемы раздувания getUserById(). Потому идея вынести их на уровень выше - в скучающую пустую доменную модель мне показалась симпатичной.
>А что значит UserHandler?
Ну я смотрел у других такие модели называются точно также как контроллеры и соответственно как разделы в урл сайта. То есть 'Users'. Мне %сущностьОбработчик% более говорящим показалось.
>Она делает важную вещь, она хранит в себе информацию о пользователе и позволяет ее передавать.
Ну сейчас сам User c этим вполне справляется.
Аноним 04/05/15 Пнд 09:47:01 #340 №473119 
>>473104
Вот же дурачек. CSS детекть с мобыли ли седить и по какой-нибудь отдельной особенности выделяй нужны элементы.
Аноним 04/05/15 Пнд 10:03:10 #341 №473124 
>>468317
Посоветуйте что можно новичку почитать о безопасности вебприложений? Вот что б прям с нуля и было объяснено почему тот код уязвим и нужно писать так.
Аноним 04/05/15 Пнд 10:44:08 #342 №473132 
Когда текст отправляется через форму исчезают абзацы. Как сделать, чтобы были?
Аноним 04/05/15 Пнд 10:47:27 #343 №473134 
>>473132
я имею в виду перенос строки(чето тупонул). Ну а вообще и абзацы тоже. В общем как сделать, чтобы текст, который написал пользователь выводился так же, как он его ввел?
Аноним 04/05/15 Пнд 11:27:10 #344 №473140 
Котаны, скажите, если объективно оценивать CodeIgniter, есть ли у него будущее? Стоит ли его использовать или лучше придрачиваться к Yii или чему-то еще популярному?
Аноним 04/05/15 Пнд 11:45:13 #345 №473148 
>>473140
На CI полно говносайтов и говноработы, впринципе, изучить его труда не составит, но не привязывайся только к нему. Есть Laravel и более кошерные вещи, с которыми работать гораздо приятнее.
Аноним 04/05/15 Пнд 11:45:19 #346 №473149 
Вопрос по Yii2. Есть таблица с полями, id, username, ...
Так вот, Users:findOne($username) ищет в id, как устроить поиск по полю username?
Аноним 04/05/15 Пнд 11:47:39 #347 №473154 
>>473132

А если открыть исходный код (Ctrl + U) то абзацев нет или там они есть? Может и не исчезают?

И второй вопрос, HTML знаешь? Про тег для абзацев или разрыва строки слыщал?
Аноним 04/05/15 Пнд 11:48:10 #348 №473155 
>>473149
Я дурак. Уже увидел
Аноним 04/05/15 Пнд 11:48:11 #349 №473156 
>>473148
> изучить его труда не составит
Мне он собственно потому и понравился что сразу все понятно сходу. Сейчас еще 3 версия вышла, я вот и размышляю, может и взлетит.
Аноним 04/05/15 Пнд 12:24:46 #350 №473177 
>>473154
ну так се. слышал, но вставлять их не хотелося.
решил с помощью функции nl2br.
Аноним 04/05/15 Пнд 12:44:00 #351 №473183 
Я понимаю что может многим надоел своими вопросами, но положение близко к критическому, уже целых 3 дня я бьюсь над одной проблемой в вордпресс и не знаю как её решить, но она элементарная.

Итак, мне надо вывести в индексном шаблоне данные из таблицы которую я создал сам. Это у меня получается, дальше мне нужно открыть эту единичную запись в отдельном шаблоне, задача стандартная. Как мне это сделать? Куда должна вести ссылка с записи в индексном шаблоне и как она должна выглядеть? Как передать ID записи через эту ссылку? Есть ли пример подобного где-нибудь? Я не использую цикл вордпресс поэтому пермалинк и подобное не подходит.
Аноним 04/05/15 Пнд 12:50:00 #352 №473186 
>>473183
ссылка должна выглядеть так
имя контроллера/имя метода(в твоем случае отображающего одну запись)/параметр(в твоем случае айди)
Аноним 04/05/15 Пнд 13:20:52 #353 №473203 
>>473186
То есть контроллер/single/12

Или вместо single надо написать какой-то метод вордпрес а не название шаблона.

Аноним 04/05/15 Пнд 13:22:29 #354 №473205 
>>473203
да, метод который есть у этого контроллера и который отвечает за показ одной записи. по идее он там уже должен быть написан
Аноним 04/05/15 Пнд 13:31:23 #355 №473211 
>>473205
Он записан если делать через стандартный цикл вордпресс, там есть удобная функция the_permalink() но тут всё по другому, так как работаю с созданной таблицей в базе данных а не с уже существующей.
Аноним 04/05/15 Пнд 13:51:48 #356 №473215 
>>472920
Хм, извиняюсь за глупый вопрос, но как сделать проверку двух массивов за один цикл? И еще почему-то пишу в цикле:
preg_match($regexp, $correctNumbers), а оно не компилится. Что не так?
Аноним 04/05/15 Пнд 14:00:35 #357 №473221 
>>473215
То есть:
>preg_match($regexp, $correctNumbers)
Аноним 04/05/15 Пнд 14:01:05 #358 №473222 
>>473221
>>473215
Да блдаж, не печатается
Аноним 04/05/15 Пнд 14:23:47 #359 №473232 
>>473111
>получается что и друзей со стенками надо там же и также создавать, а иначе как? Мапперы внутри маппера? Не круто и не решает проблемы раздувания getUserById(). Потому идея вынести их на уровень выше - в скучающую пустую доменную модель мне показалась симпатичной.
Так, я это как следует обдумал, кое-что не так страшно. Добычу связанных сущностей можно выносить в getFriendList(), getWallPosts(), getPlaylist() также как тут мы вынесли getProfile(), внутри getUserById() останется только сборка их воедино в зависимости от того жадно или лениво нужно получать. Однако дилемма 'мапперы внутри маппера' vs 'лефт джоины' внутри этих getFriendList() остается.
Аноним 04/05/15 Пнд 15:26:45 #360 №473266 
14307424059990.gif
>>473111
>Она делает важную вещь, она хранит в себе информацию о пользователе и позволяет ее передавать.
>Ну сейчас сам User c этим вполне справляется.
Ааа, я все перепутал. Доменная модель это User и есть, а этот мой не сильно нужный "UserHandler" - это то что называют service http://martinfowler.com/eaaCatalog/serviceLayer.html Вот же стыд. Меня на каком-то позорном ресурсе ввели в заблуждение. nevermind this.
Аноним 04/05/15 Пнд 16:38:34 #361 №473315 
>>468317
Поясните, пожалуйста. Всегда было интересно. В PHP запрос идет от пользователя к серверу, а есть ли обратная реализация? Как сделать к примеру, чат, который не будет атаковать сервер запросами, а наоборот, чтобы запросы шли с сервера. Вот появилось новое сообщение на сервере, он хуяк прислал его получателю, а не чтобы получатель каждое н-ное количество секунд запрашивал есть ли новое сообщение?(это как пример)
Аноним 04/05/15 Пнд 18:43:42 #362 №473378 
В слиме.

$app->config(array('templates.path' => './templates/'));

$app->get('/', function () use ($app){
$app->render('index.html');
});

Почему-то страничка не рендерится, а показывается "как есть" с тегами, и т. д. Почему?(
Аноним 04/05/15 Пнд 20:23:12 #363 №473436 
>>472761
>— BookHub, сервис для желающих обмениваться книгами
Тут надо делать аккаунт для каждого? Или достаточно просто дать возможность выкладывать книги для обмена и оставлять свои данный (телефон, емейл и т.д.)?
Аноним 04/05/15 Пнд 21:06:37 #364 №473456 
>>472322

Анон, жив ли ты еще? Я тут подумал, что твою задачу можно (наверно) решить без вызова exec вообще и без риска запустить троян. Тебе надо записать строку в COM-порт (или его аналог). В Windows (и Линукс) ком-порт доступен в виде псевдо-файла, который можно открыть и писать в него стандартными файловыми функциями, в нашем случае file_put_contents (или если ты любитель старой школы то fopen/fwrite/fclose).

Проверить успешность записи можно по результату который вернет эта функция.

Вопрос только как указать имя файла? Во времена DOS порт был доступен как псевдофайл с именем COM× и вполне возможно что сработает что-то вроде

COM9 или \COM9

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

Тогда можно попробовать исплоьзовать специальные длинные пути: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#win32_device_namespaces

Путь имеет вид \\.\COM9 но из-за экранирование бекслешей надо писать "\\\\.\\COM9" (больше бекслешей для бога бекслешей!)

В linux запись в ком-порт ведется через файл устройства где-то в /dev, может быть /dev/ttyS1 или как-то аналогично, это надо гуглить.

Ну и PHP конечно изучать надо в любом случае, чтобы не останавливаться на каждой проблеме.
Аноним 04/05/15 Пнд 21:06:39 #365 №473457 
Пасаны, не могу совладать с ООП. Прошу не серчать на говнокод.
В общем вот быдлокласс, которым я присобачиваю каптчу Яндекса как на двачике: http://pastebin.com/SPe1esQM
Дальше я получаю каптчу следующим образом:
$captcha = new yandexCaptcha($key);
$captcha_url = $captcha->get()['url'];
$captcha_code = $captcha->get()['code'];

Проблема в том, что когда я полчаю captcha_code, то, судя по всему, функция начинается с начала, опять обращается к яндексу и я получаю значение уже с другого XML, код не совпадает с URL и каптча не работает.
Что интересно, если обращатся по процедурному, типа
$captcha_url = yandexCaptcha::get()['url'];
$captcha_code = yandexCaptcha::get()['code'];
То все работает верно, а если в ООП виде, то нет.

Где я туплю?
Аноним 04/05/15 Пнд 21:10:49 #366 №473459 
>>473457
Блин, херню какую-то на пастебин залил.
Вот так правильно: http://pastebin.com/2aeX8b67
Аноним 04/05/15 Пнд 21:27:24 #367 №473466 
>>472709

Кстати. Если ты установишь расширение XDebug то var_dump будет выводить список полей вертикально и с форматированием, а не в строчку. А сообщения об ошибках будут более подробными.

>>473079

Это называется размещение, когда у нас есть N переменных которые могут принимать M значений.

Алогритм простой:

— сгенерировать все возможные размещения a и b (значение c получается как n - a - b)
— отобрать из них те которые соответствуют условию задачи
— посчитать сколько их

Как генерировать все возможные размещения? Ну в твоем случае хватит цикла:

перебрать a от 0 до максимума
для каждого a переьрать все значения b от 0 до максимума
для каждой пары a, b вычислить c и добавить в список

В более сложных случаях когда число переменных заранее неизвестно, нужны более сложные алгоритмы:

https://ru.wikipedia.org/wiki/%D0%A0%D0%B0%D0%B7%D0%BC%D0%B5%D1%89%D0%B5%D0%BD%D0%B8%D0%B5
https://ru.wikibooks.org/wiki/%D0%A0%D0%B5%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D0%BE%D0%B2/%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%B8%D0%BA%D0%B0/%D0%A0%D0%B0%D0%B7%D0%BC%D0%B5%D1%89%D0%B5%D0%BD%D0%B8%D1%8F
http://study-and-dev.com/blog/sda_theory_combinatoric/
http://cppalgo.blogspot.ru/2012/03/blog-post_20.html
http://e-maxx.ru/algo/generating_combinations
http://algolist.manual.ru/maths/combinat/

Ну и может их не обязательно генерировать, может тут можно формулами из комбинаторики посчитать.
Аноним 04/05/15 Пнд 21:38:33 #368 №473467 
>>473079

Вот математический расчет. Обозначим число конфигураций K переменных дающих в сумме N как confiCount(K, N)

В твоей задача надо найти configCount(3, N)

Попробуем определить чему равно configCount. Во-первых, для 1 переменной число конфигураций равно 1, так как есть единственное значение которое в сумме дает N:

configCount(1, N) = 1

При большем числе переменных мы можем вывести рекуррентное соотношение:

configCount(K, N) = ∑(i = от 0 до N)(configCount(K - 1, N - i))

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

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

Теперь если раскрыть эти формулы для 3 переменных, то получим:

configCount(3, N) = ∑(i = 0 .. N)(configCount(2, N - i)) = ∑(i = 0 .. N)(∑(j = 0 .. N - i)(configCount(1, N - i - j))) = ∑(i = 0 .. N)(∑(j = 0 .. N - i)(N - i - j))

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


Аноним 04/05/15 Пнд 21:43:24 #369 №473470 
>>473467

Я даже поставлю вопрос к математикам более широко: если есть выражение

∑(i = 0 .. N)f(i)

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

>>473101

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

> Просто спрашиваю может есть вещи, где фреймворки не подойдут, допустим из-за избыточности?
Фреймворки ориентированы на создание сайтов, так что если ты делаешь не сайт то они тебе не подойдут.
Аноним 04/05/15 Пнд 21:52:35 #370 №473472 
>>473104

Яваскриптом. Алсо не понимаю, зачем менять ссылки на странице.

>>473111

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

> Потому идея вынести их на уровень выше - в скучающую пустую доменную модель мне показалась симпатичной.
Это плохая идея так как ты размазываешь загрузку сущностей из БД по нескольким классам. Если метод getUserByID становится толстым то разбей его на несколько более маленьких.

> Ну я смотрел у других такие модели называются точно также как контроллеры и соответственно как разделы в урл сайта. Т
контроллеры соответствуют разделам и страницам, а модели таблицам в БД (точнее сущностям из предметной области). Их число и название не всегда совпадает.

>>473124

У меня есть 2 урока по XSS/CSRF:

https://github.com/codedokode/pasta/blob/master/security/xss.md
https://github.com/codedokode/pasta/blob/master/security/xsrf.md

По SQL инъекциям можно нагуглить статьи:

Вики: https://ru.wikipedia.org/wiki/%D0%92%D0%BD%D0%B5%D0%B4%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_SQL-%D0%BA%D0%BE%D0%B4%D0%B0
Школофорум: http://forum.antichat.ru/thread43966.html
+ статьи с хабра

http://habrahabr.ru/post/148701/

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

Аноним 04/05/15 Пнд 22:07:41 #371 №473478 
>>473140

Фреймворк из эпохи PHP4 c кучей рудиментов, не поддерживает композер по моему, фирма которая его делала его забросила. Если ты его запустишь по современным PHP то он сыплет предупреждениями, код убогий (на мой взгляд) по нынешним меркам.

>>473177

> но вставлять их не хотелося.
Если ты изучал HML то должен знать что любое число пробелов и переводов строк воспринимается как один пробел. Соответственно ты должен либо с помощью CSS и свойства white-space ( http://htmlbook.ru/css/white-space ) это менять, либо вставлять br

> решил с помощью функции nl2br.
ну так она и вставляет br

>>473183

> может многим надоел своими вопросами
Это тред специально для начинающих и вопросов от них. Задавай сколько хочешь вопросов.

> Это у меня получается, дальше мне нужно открыть эту единичную запись в отдельном шаблоне, задача стандартная. Как мне это сделать?
В архитектуре вордпресса все сущности (которые можно запостить отдельным постом и открыть на отдельной странице) — это разновидности постов. Медиафайлы, пункты меню, статические страницы — это тоже виды постов. Я советую как-то разобраться и изучить, например изучить схему БД вопрдпресса, какие там есть таблицы, почитать какие есть функции API и тд.

Ты можешь создать свои сущности через custom post types. При этом можно наверно заджойнить свою таблицу на таблицу постов либо хранить данные в дополнительных колонках (если можно заджойнить отдельную таблицу то это более красивое и надежное решение).

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

Чтение:

https://codex.wordpress.org/Post_Types
http://truemisha.ru/blog/wordpress/post-types.html
http://rightblog.ru/1967
http://habrahabr.ru/post/97247/
http://habrahabr.ru/sandbox/39487/
http://wpcafe.org/tutorials/rukovodstvo-po-kastomnyim-tipam-zapisey-wordpress/

(некоторые статьи плохие потому в первую очередт читай мануал)

Советую тебе рассмотреть вариант переделать твой тип записей на custom post type. Это сбережет силы и время.

Ну и помни что вордпресс это блоговый движок и возможности его расширения ограничены. Это не фреймворк.
Аноним 04/05/15 Пнд 22:12:12 #372 №473481 
>>473183

> Я не использую цикл вордпресс поэтому пермалинк и подобное не подходит.
Почему? Чем они не подходят? «я не осилил документацию» уважительной причиной не считается, скажу сразу.

Имхо тут нужны custom post types.

Если нет то тебе нужен свой обработчик, чтобы при обращении по определнному URL вызвыался твой код. Для этого есть такие вещи:

— WP Rewrite: https://codex.wordpress.org/Class_Reference/WP_Rewrite - наверно можно туда добавить свой обработчик как-то чтоюы например при обращении по адресу /something/NNN вызывался скрипт your_plugin.php?id=NNN
— хук: http://stackoverflow.com/a/16545672 — имхо это костыль

Аноним 04/05/15 Пнд 22:15:29 #373 №473482 
>>473457
>>473459
Ребята, ну бамп.
Аноним 04/05/15 Пнд 22:23:37 #374 №473493 
>>473186

В вордпресс есть контроллеры? Если так то анону может подойти этот вариант.

>>473215

Я не понял что значит «проверка 2 массивов»? Что тебе надо проверить?

Если тебе надо обойти все элементы 2 массивов то надо либо 2 цикла либо объединить массивы в один.

> И еще почему-то пишу в цикле:
preg_match($regexp, $correctNumbers), а оно не компилится. Что не так?
регулярка неправильная может? Покажи код

>>473232

> дилемма 'мапперы внутри маппера' vs 'лефт джоины'
По моему проблемы нет. Либо ты выбираешь огромный массив данных джойном и внутренними функциями в маппере UserMapper создаешь из них Profile,FriendsList либо если это делается отдельным запросом то это делается в другом маппере.

>>473266

Разницу по моему нетрудно запомнить. Моделей может быть много, например загрузил 10 юзеров и имеешь 10 объектов. А сервис почти всегда в одном экземпляре (разве что при тестировании ты захочешь каждый раз для чистоты эксперимента создавать новый).

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

— принимает на вход модель User (ее должен создать и заполнить тот кто вызвал метод, например контроллер)
— маппером сохраняет ее в БД
— отправляет письмо с помощью сервиса уведомлений
— увеличивает показатели стастичтики вызывая соотв. сервис
— начисляет пользователю бонусы за регистрацию

То есть сервисы обычно делают более сложные операции (бизнес-логику), а маппер это просто «глупый» низкоуровневый класс для работы с таблицей в БД.

Получается такая слоеная архитектура, где вышележащий слой использует классы из нижележащего. Опять же это разделение делается ради того чтобы в большом приложении не запутаться в коде.
Аноним 04/05/15 Пнд 22:47:18 #375 №473533 
>>473315

Да, называется вебсокет —браузер устанавливает соединение с сервером и тот может слать в него данные. Обычно вебсокт-сервер пишут на всяких Node.jS, но сейчас и в PHP есть библиотека Ractchet для этого.

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

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

>>473378

Посмотри инспектором Ctrl + shift + I на вкладке Network заголовки. в частности Content-Type

Ну и нужно больше подробностей

>>473436

Аккаунт не самоцель, цель сделать процесс обмена (и использования сайта) наиболее удобным. Я думаю, что тут аккаунт нужен, так как процесс использования выглядит так. Представим, что ты пользователь у которого есть несколько не нужных ему книг и котоый хочет их обменять на что-нибудь что он еще не читал:

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

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

Ты не должен спешить писать код. Начни с проектирования со стороны пользователя. Продумай несколько сценариев:

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

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

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

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

То есть не ставь код на первое место, начни с проектирования взаимодействия и пользовательских сценариев.
Аноним 04/05/15 Пнд 22:54:13 #376 №473543 
>>473533

Remote Address:127.0.0.1:8085
Request URL:http://localhost:8085/File_sharing/
Request Method:GET
Status Code:200 OK

Connection:Keep-Alive
Content-Length:916
Content-Type:text/templates
Date:Mon, 04 May 2015 19:51:58 GMT
Keep-Alive:timeout=5, max=100
Server:Apache/2.4.7 (Ubuntu)
Аноним 04/05/15 Пнд 22:56:14 #377 №473545 
>>473457

А зачем ты делаешь 2 вызова get() и 2 запроса к яндексу? Это же неэффективно как минимум. Сетевые взаимодействия не бесплатны и требуют времени.

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

> Что интересно, если обращатся по процедурному, типа
> То все работает верно, а если в ООП виде, то нет.
Чушь. Причина не в этом, а в чем-то другом.

Также вот еще косяки:

— имя класса с большой буквы
— работа с сетью сделана плохо, ни проверок на ощибки ни таймаутов не выставлено. ты думаешь интернет запросы в 100% случаев выполняются успешно? АПи яндекса тоже иногда выдают ошибки или не отвечают и надо это обрабатывать.
— XML в ответе тоже может быть невалидным из-за ошибки на стороне яндекса
— при подстановке данных в URL надо их кодировать процентным кодированием в urlencode иначе пользователь может видоизменить URL зароса и может быть обойти проверку

Аноним 04/05/15 Пнд 23:00:09 #378 №473551 
>>473543

> Content-Type:text/templates
Это. Тип говорит браузеру о том какого типа ответ и как его надо отобразить: как текст, HTML, картинку, аудиозапись и тд. Для HTML там должно быть text/html; charset=utf-8

Найди где выставляется тип и убери это. Ты какой-ниьудь плагин хитрый к слиму не подключил? настройки PHP не менял?

https://ru.wikipedia.org/wiki/%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA_MIME-%D1%82%D0%B8%D0%BF%D0%BE%D0%B2

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

Аноним 04/05/15 Пнд 23:00:47 #379 №473555 
>>473543
$app->contentType('text/html') помог.
Можно это как-то вначале писать, чтобы в каждом роутере не переписывать?
Аноним 04/05/15 Пнд 23:05:03 #380 №473563 
>>473551
Я удалил .htaccess, который composer стянул. Пока не удалял, вылезала 500 ошибка.
Аноним 04/05/15 Пнд 23:06:34 #381 №473565 
>>473555

Этот тип должен стоять по умолчанию. Ты какие-то плагины к слиму подключал? Сборку используешь левую или с официального сайта? В php.ini ничего не менял?

Проверить конфигурацию php можно так. Поставь в index.php код

phpinfo( );
die( );

в начало и открой страницу. Это выведет настройки PHP, там 2 колонки, значение по умолчанию и текущее. Там найди mimetype ( http://php.net/manual/ru/ini.core.php#ini.default-mimetype ), и посмотри какие значения стоят.
Аноним 04/05/15 Пнд 23:08:34 #382 №473569 
>>473555

Можно

>>473563

Странно. А правильно ли ты установил Слим? ЧТо-то странные какие-то вещи творятся. Что было в этом файле и где он лежал? Какая причина ошибки? (логи Апача с причиной лежат в /var/log/httpd или /var/log/apache2)
Аноним 04/05/15 Пнд 23:09:44 #383 №473570 
>>473545
> А зачем ты делаешь 2 вызова get() и 2 запроса к яндексу?
Так я один запрос хочу, а не два. Я не понимаю почему два раза, если я хочу вторым запросом get() всего навсего забрать из массива то, что в него уже попало. Видимо я просто не понимаю чего-то и хочу помощи.
> Мне лень смотреть, посмотри документацию, если несколько раз делать запрос для получения капчи, он вернет одну и ту же капчу или он каждый раз генерирует другую качу с другим кодом. Может ты генеируешь 2 капчи, URL беешь от первой а код от второй.
Вот именно, в этом и проблема. Я не хочу генерировать еще раз, зачем оно второй раз обращается к яндексу?
> Чушь. Причина не в этом, а в чем-то другом.
В том то и дело, что в процедурном виде все работает так, как я задумывал.
> — имя класса с большой буквы
> — работа с сетью сделана плохо, ни проверок на ощибки ни таймаутов не выставлено. ты думаешь интернет запросы в 100% случаев выполняются успешно? АПи яндекса тоже иногда выдают ошибки или не отвечают и надо это обрабатывать.
> — XML в ответе тоже может быть невалидным из-за ошибки на стороне яндекса
Это все пока пофигу.
> — при подстановке данных в URL надо их кодировать процентным кодированием в urlencode иначе пользователь может видоизменить URL зароса и может быть обойти проверку
Хрен там, не даст движок ничего запостить пока не получит от Яндекса <ok />
Аноним 04/05/15 Пнд 23:11:11 #384 №473573 
>>473569
Создал проект в phpstorm как Composer'ский, указал слим (slim/slim). Как проект создался, подключил еще bootstrap.
Аноним 04/05/15 Пнд 23:21:47 #385 №473590 
>>473570

> Я не понимаю почему два раза, если я хочу вторым запросом get() всего навсего забрать из массива то, что в него уже попало. Видимо я просто не понимаю чего-то и хочу помощи.
когда ты пишешь

$object->doSomething()

(обрати внимание на скобки) то это вызов метода. Вызов метода значит что PHP заходит в него и выполняет написанный внутри него код (и шлет запрос на сервер яндекса, и разбирает его и т д). Поставь в начале метода

echo "Send request...\n";

и посмотри сколько раз выведется эта надпись.

Если что, «метод» это функция у объекта.

Если ты 2 раза пишешь $captcha->get() то код в методе выполняется тоже 2 раза и отправляется 2 запроса. Обязательно поставь туда echo и посчитай сам.

> Я не хочу генерировать еще раз, зачем оно второй раз обращается к яндексу?
Потому что ты 2 раза вызываешь метод и таким образом 2 раза просишь PHP выполнить код, написанный в нем.

PHP просто выполняет команды которые ты написал последовательно, сверху вниз. Он не думает о том, что например у нас уже есть массив и мы могли бы не обращаться к серверу. Если ты говоришь ему выполнить метод 2 раза то он его и выполнит 2 раза.

> В том то и дело, что в процедурном виде все работает так, как я задумывал.
Поставь туда echo перед отправкой запроса и посмотри сколько раз выведется текст.

> Хрен там, не даст движок ничего запостить пока не получит от Яндекса
Это все равно уязвимость. Пользователь может дописать к запросу произвольное число отдельных параметров. Чтобы понять чем это опасно надо изучить всю докуменатацию по АПИ. Ну условно говоря может там есть параметр типа test=1 который выдает ok независимо от результат или параметр типа deleteMyAccount=1 который вообще удаляет аккаунт.

Так что ты зря споришь. Надо делать нормально, чтобы сразу было видно что тут все безопасно а не так что «может тут и есть уязвимость»
Аноним 04/05/15 Пнд 23:39:26 #386 №473607 
>>473590
Та верю я тебе, вижу что два раза вызывается, просто я не понимаю почему. Я вообще не программист и в этом месте догнать не могу.
> Пользователь может дописать к запросу произвольное число отдельных параметров.
Там примитивное АРІ, максимум это он может еще и отправить свое сообщение в Яндекс на спам-проверку. И вообще, как я и говорил, это все пока пофигу. Это полуработующий пример, какая разница что куда можно подставить на локалхосте и какие имена классов, лол.
Аноним 04/05/15 Пнд 23:48:49 #387 №473615 
Котаны, поясните можно ли при помощи одного ПХП и ХТМЛ сделать такое http://neave.tv ? Я как то не в курсе работы с видео на ПХП и вообще не понимаю как организовать подобный телевизор.
Аноним 04/05/15 Пнд 23:59:11 #388 №473623 
>>473607

Потому что ты написал 2 раза команду «вызвать метод который отправляет запрос к яндексу». ты написал команду 2 раза, она 2 раза выполнилась и 2 раза отправила запрос.

> Я вообще не программист
Тогда передай эту задачу программисту

>>473615

Я не заходил на сайт, но просто возпроизвети видеофайл можно тегом video из HTML 5. более сложные вещи делаются на явакрипте (раньше на флеше делали, но он умер).

Аноним 05/05/15 Втр 00:04:03 #389 №473629 
>>473623
> Потому что ты написал 2 раза команду «вызвать метод который отправляет запрос к яндексу». ты написал команду 2 раза, она 2 раза выполнилась и 2 раза отправила запрос.
Что ты из пустого в порожнее переливаешь? Знаю я что сделал, не знаю как правильно сделать. Подскажи лучше.
> Тогда передай эту задачу программисту
Как я понял это тред для новичков. Чего ты из себя илитку корчишь?
Аноним 05/05/15 Втр 00:22:46 #390 №473645 
>>473629

Если ты не программист и тебе главное решить задачу, и у тебя есть код который работал (процедурный), то зачем что-то исправлять? Просто бери код который работал и используй и забудь про ООП. Зачем время тратить на это?

Если ты хочешь научиться делать правильно или разобраться как это работает, то начинай изучение PHP с самого начала, с переменных, циклов, функций, и тд., а не берись сразу за сложные вещи. Тут есть учебник в первом посте.
Аноним 05/05/15 Втр 00:26:02 #391 №473650 
>>473623
>Я не заходил на сайт, но просто возпроизвети видеофайл можно тегом video из HTML 5. более сложные вещи делаются на явакрипте (раньше на флеше делали, но он умер).
Суть в том что при нажатии на кнопку плей, начинает воспроизводится другое видео. Я это только что попытался сделать на ПХП, скачал плейер, поместил в массив адреса нужных мне видео, через rand начал выбирать из массива случайные видео и подключать их в плейер но сделать это у меня получилось только при помощи кнопки формы, то есть под видео есть кнопка формы нажимаешь на ней и видео меняется, но мне надо что бы оно менялось при нажатии на плей.
Аноним 05/05/15 Втр 00:27:41 #392 №473651 
>>473650

Это надо с яваскриптом заморачиваться. PHP работает на севрере до отображения страницы, а яваскрипт в браузере уже во время этого.

Аноним 05/05/15 Втр 00:31:45 #393 №473653 
>>473651
Я яваскрипт вообще не знаю, есть код самого плейера, но я мало что могу в нём понять, я так понимаю надо что то сделать что бы при определённом событии таком как нажатие на плей менялось видео, но как детектировать где там плей в этом коде.
Аноним 05/05/15 Втр 01:02:27 #394 №473658 
>>473645
Я играюсь и пишу сорт оф гостевуху, просто так, от скуки. Вот написал все процедурно, стало скучно, решил переписать классами и наткнулся на проблему. Я, как сисадмин по профессии, не воспринимаю линейные книги, только научным методом. Впрочем, так и скажи, что сам не знаешь, чего демагогию разводить на пару постов.
Аноним 05/05/15 Втр 02:06:17 #395 №473684 
>>473658

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

>>473653

Мне что-то лень разбираться в чужом коде. Попробуй сам разобрать, например отладчиком в браузере (Ctrl + Shift + i) посмотри что там происходит на сайте. Вот статья про отладчик: http://habrahabr.ru/post/143767/

Аноним 05/05/15 Втр 02:43:52 #396 №473692 
>>473684
> Твоим методом ты ничему не научишься
А вот и не правда. Додумался перенести часть, отвечающую за скачивание XML-ки с Яндекса в __construct, теперь все четко работает.
Аноним 05/05/15 Втр 05:18:18 #397 №473723 
>>473467
>>473466
Добра вам, анончики
Аноним 05/05/15 Втр 05:52:16 #398 №473724 
>>473569
Все, нашел. Эта ошибка возникает, когда в apache2.conf в теге Directory написано AllowOverride All.
Как тогда делать, чтобы адрес был такой project/name, а не project/index.php/name?
Аноним 05/05/15 Втр 09:36:34 #399 №473748 
14308077948130.png
>>473493
>По моему проблемы нет. Либо ты выбираешь огромный массив данных джойном и внутренними функциями в маппере UserMapper создаешь из них Profile,FriendsList либо если это делается отдельным запросом то это делается в другом маппере.
С первым вариантом все понятно. А вот второй... (пикча) Перечитал немало дискуссий на тему DAO inside another DAO, вощемта, все сходятся во мнении что это зло. Как по-другому вызвать другой маппер вне текущего я хоть убей не вижу.
>Разницу по моему нетрудно запомнить.
Да говорю ж где-то подцепил заразу о том что user это типа entity model, а userhandler/userservice - domain model. А может не про php шла речь. Больше не перепутаю
Кстати, угадай с чем я столкнулся в getFriendList? Проблема n+1. Тут перфекционизм оказался очень кстати я прям сразу увидел что foreach(100 раз) { 'SELECT * ' } это вообще не круто и даже сам ее решил через промежуточный запрос, а потом SELECT ... WHERE ... IN (). А потом уже вспомнил что ты про нее предупреждал.
Аноним 05/05/15 Втр 10:01:01 #400 №473756 
>>473748
>Как по-другому вызвать другой маппер вне текущего я хоть убей не вижу.
ААА, нет, стоп-стоп-стоп, придумал!
вместо
$playlist = $this->getPlaylist($id);
$proxy_playlist = ProxyPlaylist::createGreed($playlist);
будет
$playlist= new Playlist;
$proxy_playlist = ProxyPlaylist::createGreed(new MusicMapper, $playlist);
А внутри прокси уже делай что хочешь!
Аноним 05/05/15 Втр 12:50:07 #401 №473809 
14308194070150.png
Извините, если задаю глупый вопрос. Есть база mysql. При удалении записи с id других записей ничего не происходит - соответственно, происходит пропуск. Как обновить id, чтобы стало 1, 2, 3 ?
Аноним 05/05/15 Втр 13:10:30 #402 №473814 
>>473809

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

В твоем случае вообще можно генерировать номера на стороне PHP наверно, а не хранить их в базе.

>>473756

> Как по-другому вызвать другой маппер вне текущего я хоть убей не вижу

Нужен вышестоящий объект хранящий в себе все мапперы (или создающий их по мере необходимости).

В доктрине для этого есть метод у EntityManager: $em->getRepository('Friends')

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

$proxy = $manager->createProxyFor('Friends', $id)

В доктрине по моему этот метод наызвается createReference.

С его помощью мы получаем прокси для любого маппера и любого id.

> Да говорю ж где-то подцепил заразу о том что user это типа entity model, а userhandler/userservice - domain model
entity это сущность, например Пользователь, Пост и тд.

domain model — модель предметной области — http://en.wikipedia.org/wiki/Domain_model — так часто называют все сущности и связи между ними вместе.

Тут действительно есть путаница что иногда моделью называют 1 класс, а иногда все вместе.

> и даже сам ее решил через промежуточный запрос
да, при жадной выборке надо выбирать связанные сущности через WHERE IN.

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

Ну и как я писал выше, можно вообще сделать умную систему которая анализируя статистику о ленивых загузках определяет какие сущности надо загружать жадно, а какие лениво так, чтобы минимизировать число запросов или еще какие-то критерии.
Аноним 05/05/15 Втр 13:13:34 #403 №473816 
>>473533
ого, круто. я ещё вчера Autobahn|JS нагуглил,
это то же самое, что и Ractchet, только на js, или нет? Возможно, Ractchet это серверное решение, а Autobahn|JS клиентское?
но для вебсокета нужно поднять отдельный сервер, или как? На обычном хостинге это возможно?
Аноним 05/05/15 Втр 13:13:48 #404 №473817 
>>473724

> Эта ошибка возникает, когда в apache2.conf в теге Directory написано AllowOverride All.
Это не причина ошибки. Ты просто отключил чтение файла htaccess (в котором настоящая ошибка). Причина ошибки в логах, посмотри их.

> Как тогда делать, чтобы адрес был такой project/name, а не project/index.php/name?

Исправить эту ошибку, так как она явно связана с ошибкой в htaccess файле. А htaccess файл нужен чтобы работали красивые URL, он перенаправляет все обращения к сайту на index.php

Аноним 05/05/15 Втр 13:15:12 #405 №473818 
Подскажите как решить проблему форматирования дат в MySQL?
По умолчанию в базе даты хранятся в виде yyyy-mm-dd, а на сайте должны выводиться в привычном виде dd.mm.yyyy.
Сейчас у меня две функции под это дело написаны, которые гоняют дату туда сюда из одного формата в другой, можно как-нибудь избавиться от этого костыля?

Так же интересует вопрос, как сделать так, что бы таймстамп ставился в столбец created при создании записи, а при изменении timestamp ставился в столбец edited
Аноним 05/05/15 Втр 13:20:55 #406 №473820 
>>473816

> но для вебсокета нужно поднять отдельный сервер, или как?
Твое PHP приложение и есть сервер. Оно само открывает порт, принимает запросы и передает данные. Ты должен его прописать в автозагрузку (в линуксе это bash-скрипт в папке /etc/init.d, а в системах с новомодным systemd это конфиг-файл в какой-то папке) на сервере, причем запускать надо не напрямую, а из-под программы супервизора вроде monit, supervisord которая будет вести логи, перезапускать при падениях и тд.

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

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

на сайте же написано:

> provides an open-source implementation of The Web Application Messaging Protocol (WAMP) .

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

в Ratchet есть модуль для поддержки WAMP на сервере.
Аноним 05/05/15 Втр 13:24:42 #407 №473823 
>>473818

> Сейчас у меня две функции под это дело написаны, которые гоняют дату туда сюда из одного формата в другой, можно как-нибудь избавиться от этого костыля?
При загрузке из Бд надо делать преобразование дат. Не знаю что ты за функцию написал, но из MySQL формата преобразуется так:

$timestamp = strtotime($mysqlDate);
$datetime = new DateTime($mysqlDate)

А обратно так:

$mysqlDate = date('Y-m-d H:i:s', $timestamp);
$mysqlDate = $datetime->format(...);

> как сделать так, что бы таймстамп ставился в столбец created при создании записи, а при изменении timestamp ставился в столбец edited

http://stackoverflow.com/questions/4897002/mysql-current-timestamp-on-create-and-on-update
https://dev.mysql.com/doc/refman/5.0/en/timestamp-initialization.html
http://baron.su/content/mysql-i-avtomaticheskoe-obnovlenie-taymstampov

> Вместе с тем, мне больше по душе другой вариант, реализация через триггеры
Вот это не делай

Аноним 05/05/15 Втр 13:38:09 #408 №473831 
>>473820
а как запустить приложение на хостинге?
Аноним 05/05/15 Втр 13:45:57 #409 №473838 
>>473831

так же как и любую другу программу. из командной строки ssh. Хостинг может запрещать долгоживующие приложения, имей в виду.
Аноним 05/05/15 Втр 13:47:35 #410 №473839 
>>473831

вот тут можно почитать по основы командной строки: https://gist.github.com/codedokode/10539568

Нужен ssh доступ разумеется.

По умолчанию при завершении ssh сессии прогаммы запущенные из нее завешаются, обойти это можно команжой nohup
Аноним 05/05/15 Втр 13:48:58 #411 №473840 
>>473839
спасибо!
то есть в принципе на хостинге можно запустить любую программу?
Аноним 05/05/15 Втр 14:04:45 #412 №473854 
>>473814
>то можно обращаться к нему и получать маппер из него. Или что лучше, можно сделать в этом объекте метод для создания прокси с указанным маппером
Все, кристально ясно.
А вот нужно ли вообще делать опцию жадно/лениво для загрузки юзеров через getFriendList, getCommunityMembers и т.д.? Не могу так сходу представить зачем много юзеров может целиком понадобиться. Код бы упростился.
Аноним 05/05/15 Втр 14:17:36 #413 №473868 
>>473823
Спасибо за пояснения. У меня теперь следующий вопрос: Если я хочу хранить все даты в базе в едином формате, то мне придется хранить их в формате TIMESTAMP? Я хотел бы хранить их в DATETIME просто. Но не получилось создать столбец
с типом DATETIME и атрибутом on update current timestamp.

Видимо этот атрибут можно делать только с типом timestamp? Вообще прочитал про типы http://www.mysql.ru/docs/man/DATETIME.html
http://www.spravkaweb.ru/mysql/sql/vartype
и у меня собственно возникло ощущение, что хоть TIMESTAMP и выглядит в базе точно так же как DATETIME
но
>TIMESTAMP Дата и время в формате timestamp. Однако при получении значения поля оно отображается не в формате timestamp, а в виде ГГГГММДДЧЧММСС, что сильно умаляет преимущества его использования в PHP

и по факту я буду иметь столбцы с разными форматами, и мне придется писать дополнительные php функции для приведения дат к одинаковому виду.


>Не знаю что ты за функцию написал, но из MySQL формата преобразуется так...
Вот мои функции конвертирования дат:
http://ideone.com/y1OyPi

Аноним 05/05/15 Втр 15:32:11 #414 №473926 
Как можно оптимизировать запрос
"SELECT DISTINCT orders.id, orders.user_id,orders.area,orders.address, orders.user_name, orders.email, orders.phone, orders.address,DATE_FORMAT(orders.time_order, '%d:%m:%Y %H:%i') FROM orders, rule_group, rul_areas WHERE rule_group.id_units='7' AND rule_group.id_group=orders.us_g AND rul_areas.id_agency='3' AND rul_areas.id_area=orders.area OR orders.user_id='0' ORDER BY orders.id DESC LIMIT 0, 50"

Тут суть в том, что менеджерам в зависимости от их отдела и региона показываются заказы(допустим одному менеджеру показывает одну группу пользователей, а другому другую). Но у пользователей не зарегистрированных на сайте нет группы и их не отображает в запросе, поэтому пришлось дописать "OR orders.user_id='0'"(гостям присвается айди равный нулю).
Так вот, когда в конце появляется OR orders.user_id='0' запрос начинает работать так медленно, что браузер не всегда дожидается его выполнения.
Это странно, вроде всё просто, даже некуда оптимизировать.

Повторюсь: дело не в основном запросе, он работает мгновенно, долго выполняется только когда в конце я прописываю OR.(не ругайте, запрос не я писал)
Аноним 05/05/15 Втр 16:23:13 #415 №473943 
Где HTML тред, мужики?
Аноним 05/05/15 Втр 16:24:23 #416 №473944 
>>473943
нету, абу трет все html треды, не хочет конкуренции
Аноним 05/05/15 Втр 18:48:25 #417 №473999 
>>473854

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

Как я понимаю, загрузка FriendsList идет в 2 (или 3) этапа:

1) грузим список друзей + мин. инф. о юзере одним джойном (или 2 запросами, первым получаем id, вторым самих пользователей)
2) если надо, грузим что-то еще для этих пользователей жадно отдельными запросами.

Второй этап по моему можно как-то сделать за счет кода в UserMapper, разве нет? То есть сделать в юзер-маппере функцию вроде preloadUserData(User[] $users, array $greedyLoad) и вызывать ее. ну и все функции которые выбирают пользователей, могли бы ее использовать.

Ну это так, просто рассуждения, если не надо то можешь это не делать.
Аноним 05/05/15 Втр 18:53:25 #418 №474000 
>>473868

> Но не получилось создать столбец
с типом DATETIME и атрибутом on update current timestamp.
Почитай разниц между этими тиами. DATETIME это абстрактное время без указания часового пояса. TIMESTAMP это настоящее время с часовым поясом, которое однозначно определяет точку во времени.

> Дата и время в формате timestamp. Однако при получении значения поля оно отображается не в формате timestamp, а в виде ГГГГММДДЧЧММСС, что сильно умаляет преимущества его использования в PHP
По моему это давно неактуально. Ты можешь проверить на практике, сделав запрос. Ну и если что то такой формат тоже можно распарсить.

> и мне придется писать дополнительные php функции для приведения дат к одинаковому виду.
Это часть задачи преобразователя данных между БД и PHP. Если ты захочешь true/false хранить то их тоже придется в 0/1 преобразовывать например.

> Вот мои функции конвертирования дат:
Они время не сохраняют, я бы сразу время приписал.
Аноним 05/05/15 Втр 19:23:34 #419 №474015 
Бартцы, есть тут те, кто проходил по симфони сертификацию?
Аноним 05/05/15 Втр 19:45:16 #420 №474028 
14308443163870.jpg
>>473999
О, блин, всякий раз когда я думаю что уже достиг дна боли мне стучатся снизу. Что если потребуется передавать параметры для выборок самих связанных сущностей? Например, если мне нужны не все друзья, а первые 5, или песни определенного жанра? Раздувать параметры исходного метода?
getUserById($id, $friend_limit, $favorite_music_genre)
Да нет, нереально такой балаган потом разгрести. Да это вообще нереально сделать.
Аноним 05/05/15 Втр 20:11:57 #421 №474038 
>>473926

> Но у пользователей не зарегистрированных на сайте нет группы и их не отображает в запросе, поэтому пришлось дописать "OR orders.user_id='0'"(гостям присвается айди равный нулю).
Неправильно, надо писать NULL так как если ты пишешь 0 то ты не можешь проставить внешние ключи (а ты их не проставил, зря, почитай на досуге статью http://denis.in.ua/foreign-keys-in-mysql.htm )

Также у тебя не стоят скобки и я не понимаю к чему именно относится OR. Если ты смешиваешь AND/OR надо ставить скобки чтобы не было путаницы. Я наизусть их приоритеты не помню.

> Так вот, когда в конце появляется OR orders.user_id='0' запрос начинает работать так медленно,
> Это странно, вроде всё просто, даже некуда оптимизировать.
Если все так просто почему он долго работает? Если бы все было просто то умение оптимизировать было бы не нужно — все бы само работало.

Все зависит от версии MySQL (старые не умеют мерджить индексы при OR) и от наличия индексов в табице. Оптимизация сложная тема и требует практики. Вот тебе список статей для изучения; прочти их все после чего попробуй сделать EXPLAIN и выяснить из него причину тормозов.

Ты можешь запостить результат EXPLAIN, я тоже гляну и скажу на что еще можно обратить внимание. Также напиши какие индексы есть (увидеть можно сделав SHOW CREATE TABLE x) и какие из них по твоему mysql могла бы использовать тут.

Ссылки вот в этом уроке: https://gist.github.com/codedokode/10539213#%D0%98%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D1%8B

Скопирую их сюда

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/
Аноним 05/05/15 Втр 21:12:58 #422 №474074 
>>473926

Современные весии MySQL умеют объединять индексы при OR (разумеется для этого нужные индексы должны существовать). Это описано тут

https://dev.mysql.com/doc/refman/5.0/en/index-merge-optimization.html (англ)

Если у тебя есть индекс по x и по y то запрос WHERE x = 1 OR y =2 сможет использовать оба (до 5-й версии этот запрос не мог использовать индексы вообще). Но у тебя там в запросе еще ORDER так что все чуть сложнее чем в моем примере.

Но прочти сначала статьи по ссылкам.

>>474028

> Например, если мне нужны не все друзья, а первые 5, или песни определенного жанра? Раздувать параметры исходного метода?
Лучше несколько методов. А они могут вызывать универсальный внутренний метод выборки.

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

В доктрине (я же советовал тебе ее изучить) вообще есть минимум 3 варианта (перечислены тут http://doctrine-orm.readthedocs.org/en/latest/reference/working-with-objects.html#querying ). Для простых случаев там есть такой метод:

http://doctrine-orm.readthedocs.org/en/latest/reference/working-with-objects.html#by-simple-conditions

> $tenUsers = $em->getRepository('MyProject\Domain\User')->findBy(array('age' => 20), array('name' => 'ASC'), 10, 0);

Аргументы функции find такие: http://www.doctrine-project.org/api/orm/2.2/class-Doctrine.ORM.EntityRepository.html#_find

Также условия можно указать объектом класса Criteria:

http://doctrine-orm.readthedocs.org/en/latest/reference/working-with-objects.html#by-criteria

Для сложных случаев ты пишешь запрос на языке DQL напоминающем SQL:

http://doctrine-orm.readthedocs.org/en/latest/reference/working-with-objects.html#by-dql

Да, они сделали свой язык запросов, свой парсер этого языка, дерево узлов AST и еще кучу всего. Я же предупреждал?

Тебе впрочем наверно можно обойтись без своего языка.
Аноним 05/05/15 Втр 21:13:57 #423 №474075 
>>474028

4 аргумента у функции это терпимо. 4-5 это максимальный разумный предел.

Аноним 05/05/15 Втр 21:36:37 #424 №474096 
>>468317
привет
чему будет равно
$var = null;
return isset($var);
и почему?
Аноним 05/05/15 Втр 21:40:55 #425 №474102 
>>473926
во первых, сделай INNER JOIN с условием вместо FROM , ,
во вторых сделай EXPLAIN и посмотри
Аноним 05/05/15 Втр 21:48:27 #426 №474105 
>>474096

мануал по isset читал? там написано

>>474102

INNER JOIN равносилен выборке из 2 таблиц с WHERE и на производительность вряд ли влияет, только на читаемость

Аноним 05/05/15 Втр 21:51:13 #427 №474109 
http://ideone.com/6u6Pfe
Аноним 05/05/15 Втр 21:56:33 #428 №474111 
Почему в методе вот такой код не работает:

$rus=array('А','Б','В','Г','Д','Е','Ё','Ж','З','И','Й','К','Л','М','Н','О','П','Р','С','Т','У','Ф','Х','Ц','Ч','Ш','Щ','Ъ','Ы','Ь','Э','Ю','Я','а','б','в','г','д','е','ё','ж','з','и','й','к','л','м','н','о','п','р','с','т','у','ф','х','ц','ч','ш','щ','ъ','ы','ь','э','ю','я',' ');
$lat=array('a','b','v','g','d','e','e','gh','z','i','y','k','l','m','n','o','p','r','s','t','u','f','h','c','ch','sh','sch','y','y','y','e','yu','ya','a','b','v','g','d','e','e','gh','z','i','y','k','l','m','n','o','p','r','s','t','u','f','h','c','ch','sh','sch','y','y','y','e','yu','ya','-');

$upload->name = str_replace($rus, $lat, $upload->name);

То есть не меняет кирилицу на латиницу, в то время как в процедурном стиле спокойно меняет.
Аноним 06/05/15 Срд 00:46:17 #429 №474233 
>>473943
https://2ch.hk/wrk/res/267603.html
Аноним 06/05/15 Срд 01:14:11 #430 №474241 
>>474111
http://ideone.com/Il9EbG
Аноним 06/05/15 Срд 03:32:58 #431 №474266 
У меня у одного composer иерархию хуевую делает? какой-нибудь vendor/slim/slim/index.php. имеет ли смысл вручную переносить все эти папки (css, templates,classes...) в vendor, или composer'у виднее?
Аноним 06/05/15 Срд 03:36:26 #432 №474267 
>>474266
я имею ввиду, чтобы было
vendor
----css
----templates
----classes
----....
----autoload.php
----index.php
Аноним 06/05/15 Срд 03:56:16 #433 №474270 
>>474266

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

Аноним 06/05/15 Срд 05:32:51 #434 №474283 
ЧЯДНТ?
http://ideone.com/kff7y8
Аноним 06/05/15 Срд 07:42:16 #435 №474301 
Что лучше: передавать в метод массив с избыточными данными, или передавать нужные элементы массива, что длиннее.
Аноним 06/05/15 Срд 09:00:20 #436 №474309 
>>474105
Влияет, сделай explain - inner join быстрее
Аноним 06/05/15 Срд 09:04:09 #437 №474310 
>>474074
Это просто ужас. Все на что меня хватит это
getUserById($id, $method = LOAD_LAZY, array $conditions)
Пример $conditions: ['friendlist' => ' LIMIT 10', 'playlist' => ' AND genre = jazz' ]
там свичи, дальше рассовывание по конструкторам менеджера проксей, передача в мапперы и конкат в конец запроса
>Лучше несколько методов. А они могут вызывать универсальный внутренний метод выборки.
Имеешь ввиду что-то типа
UserMapper
{
getUserById ($id) {... return getUser(['user_id'],[$id])}
getUserByEmail ($email) {... return getUser(['email'],[$email])}
getUserByEmailAndPassword ($email, $password) {... return getUser(['email','password'],[$email,$password])}
getUser(array $fields, array $values, array $conditions) {тут вся логика выборки}
}
?
Аноним 06/05/15 Срд 10:49:54 #438 №474321 
Есть еще 1 вопрос по Базам данных.

Вот есть у меня например таблица юзеров
user_id
user_name

Далее таблица задач
task_id
task_title
task_body
user_id //кто создал задачу, связано с user_id в юзерах

Далее допустим я хочу сделать 3 таблицу с комментариями
comment_id
comment_body
task_id //кто над ней работает и оставляет комментарии, связано с task_id
user_id // и теперь вот тут ВОПРОС я хочу связать это поле с user_id в юзерах. Можно ли так делать? У меня получится замкнутый круг из связей. Или это сразу фейл в проектировке базы?
Аноним 06/05/15 Срд 11:02:44 #439 №474327 
>>474321
Спокойно можно, в этом суть реляционных баз. Никакого замкнутого круга нет.
Аноним 06/05/15 Срд 11:10:44 #440 №474330 
>>474327

Ты прав, я что-то затупил, это ведь у comment будет как бы 2 родительские, а сам он может быть удален.
Я ставлю там галочки on update restrict
Так что теперь невозможно почти ничего удалять в базе, только если прям подчистить все комментарии.
Аноним 06/05/15 Срд 13:07:35 #441 №474356 
>>474330
Ну было бы странно вместе с коментом удалять автора или запись где он сделан. restrict в 95% правильный выбор.
Аноним 06/05/15 Срд 14:50:55 #442 №474416 
14309130553370.jpg
>>474038
>>474074
>>474102
Спасибо большое, сижу читаю, вот explain
Аноним 06/05/15 Срд 14:55:04 #443 №474418 
14309133048500.jpg
>>474416
извиняюсь, случайно склеил индексы
Аноним 06/05/15 Срд 16:57:05 #444 №474466 
>>474310

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

найти юзера по id и по условию

Если у тебя есть id зачем тебе условие? Это должны быть 2 отдельные функции, вроде find в доктрине (ищет 1 запись по id), findBy (ищет много по условию) и findOneBy (ищет 1 по условию). Ну и дополнительные функции если нужны какие-то специфичные выборки. Все уже придумано до нас.

> getUserByEmai
Доктрина реализует метод findBySomething для любого поля за счет магического метода call, но тебе думаю проще использовать массив чтобы искать по email.

>>474321

Не можно а нужно прописать связи с помощью внешних ключей: http://denis.in.ua/foreign-keys-in-mysql.htm

Праивльная мысль.

>>474356

Там условие имеет другой смысл: надо ли удалять комментарии при удалении их автора. Или же надо запрещать такое? Или же менять user-id на NULL у комментария?

>>474416

Ты прочел статью про типы выборки и про индексы? Прочти тут внимательно http://www.mysql.ru/docs/man/EXPLAIN.html

MySQL не обладает какой-то особой магией. Если в запросе несколько таблиц, она должна выбрать все подходящие записи из первой, присоединить к каждой записи из второй и так далее. Без индексов это дает огромное число записей и как следствие медленный запрос. Индекс если ты прочел статью, позволяет делать 2 вещи:

— быстро отобрать небольшую часть записей по условию, например WHERE x = 1
— отобрать записи в отсортированном порядке например в случае ORDER BY x LIMIT 10 индекс по x значительно ускорит запрос.

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

Теперь разберем твой запрос.

У тебя в первой строчке стоит type = ALL. Это самое плохое (если только у тебя в таблице не 10 строк), это полный обход всей таблицы, самый медленный способ выборки.

В колонке rows видно что читается 7000 строк (что кстати немного и такое число за долю секунды обходится если памяти достаточно).

Почему так? давай посмотрим правее:

possible_keys — какие индексы теоретически можно было бы использовать
key — какой был использован (никакой не был, потому и тип ALL)

Если посмотреть на запрос и посмотреть какое у нас стоит условие выборки из orders:

SELECT FROM orders ... WHERE (.... условия к другим таблицам ... ) OR order.user_id = 0

Условие OR тут не дает применить индекс так как за счет OR в выборку попадают не только записи где user_id = 0, а и с любым другим значением.

По той же причине нельзя начать с таблицы rule_group и выбрать из нее записи с id_units = 7 так как OR нейтрализует это условие делая его необязательным.

Соответственно мы имеем полный перебор таблицы, к каждой строчке присоединяется аж по 40 строк из второй и к каждой этой строке присоединяется по 200 строк из третьей. Тип index который там использован это второй после all по медленности. Это уже скорее всего из-за отстутсвия нужных индексов.

Тебе надо попробовать как-то переписать запрос. Так, чтобы можно было отобрать небольшую часть записей из одной таблицы и присоединять к ним другие индексом. Может тут стоит вместо user_id = 0 испольщовать LEFT JOIN вместо INNER JOIN который ты используешь.

Если ты плохо понял о чем я пишу, то вернись к индексам и изучи их пока не начнешь понимать. Я могу подсказать что-то по простым примерам, например с одной таблицей.
Аноним 06/05/15 Срд 17:02:45 #445 №474472 
>>474109

Молодец, все верно почитал.

>>474111

str_replace работает одинаково везде. Сделай короткий пример кода где он не работает и выложи на ideone, мы глянем. Также ты можешь глянуть в логи php (по моему они в папке Апача по умолчанию) и поискать там причину ошибки. У тебя наверно вывод ошибок на экран отключен и ты их не видишь.

Вот у этого >>474241 анона все работает.

>>474267

Твой код должен быть снаружи vendor. Это позволяет легко увидеть где чей код.

>>474283

preg_match находит только первое совпадение с шаблоном. То что он вернул это массив с кусками найденного текста.

Чтобы найти все совпадения нужен preg_match_all он есть в мануале и в уроке где-то описан.

>>474301

Сложно сказать в абстрактном случае. Покажи заголовок и название функции.

>>474309

Диванные оптимизаторы пожаловали в тред?

Аноним 06/05/15 Срд 19:24:43 #446 №474535 
>>474472
>Чтобы найти все совпадения нужен preg_match_all он есть в мануале
Очень ленюсь читать что-то кроме урока (а там до задания точно не было про all), надо побороть это в себе.
Все правильно теперь?
http://ideone.com/kff7y8
Аноним 06/05/15 Срд 19:26:18 #447 №474536 
>>474535
А там, про preg_match_all сразу после задания написано, извиняюсь.
Аноним 06/05/15 Срд 20:05:07 #448 №474547 
Столкнулся с элементарной проблемой, которую кажется уже решал, но сейчас что то не получается. Есть страница одиночного поста и выглядит её ссылка примерно подобным образом:

blog.com/single.php?id=12

Мне надо подключить к этому посту возможность комментирования, но после нажатия кнопки (submit) в форме, id из ссылку убирается а следовательно и убирается сам пост, остаётся только пустой шаблон. Как избежать этого?
Аноним 06/05/15 Срд 20:30:32 #449 №474563 
>>474547
В дополнении скажу что попробовал решить эту проблему тем способом, что вынес добавку комментария на другую страницу, на которую помимо всех нужных данных передаю в скрытой форме id записи, если всё успешно добавляется то делаю обратно перенаправленнее на страницу вывода поста и передаю через ссылку переменную в этим самым id который сохранил в скрытой форме. Это кажется очень костыльно.
Аноним 06/05/15 Срд 20:42:55 #450 №474569 
Ребят, хтмлакадеми и кодекадеми хватит для достаточного знания хтмл и ксс? Достаточно, для человека не позиционирующего себя как верстальщика.
Аноним 06/05/15 Срд 20:59:22 #451 №474579 
14309351623810.jpg
ОПчик-сиропчик, я недавно получил свою первую зарплату, как пхп кодер.
Огромный тебе респект за твои задачи и помощь. Ты очень хороший человек.
И респект все тем кто помогал и помогает новичкам в этом треде.

Люблю вас
Аноним 06/05/15 Срд 21:02:01 #452 №474582 
>>474579
О, это очень неплохо, какие тестовые задания были при приёме на работу, какими скилами обладал когда устраивался?
Аноним 06/05/15 Срд 21:54:30 #453 №474613 
Никак не могу понять, почему result не выводит.
http://ideone.com/cayqOl
sageАноним 06/05/15 Срд 21:59:48 #454 №474615 
>>474613
я тож)))0
Аноним 06/05/15 Срд 22:01:12 #455 №474616 
>>474615
>PHP Notice: Undefined variable: testNumder in /home/E5g0Ke/prog.php on line 20
>PHP Notice: Undefined variable: testNumder in /home/E5g0Ke/prog.php on line 21
Аноним 06/05/15 Срд 22:02:48 #456 №474619 
>>474616
>>474613
Аноним 06/05/15 Срд 22:05:58 #457 №474622 
>>474582
Хочешь расскажу? у меня тестовым заданием было написать хуйню, которая считает среднее арифметическое всех элементов массива. Я подумал что это задание с подвохом, вспомнил посты ОП-а, когда в каждом таком случае он на мои несколько строк в коде придлагал готовую php-функцию
и написал
$a = array_sum($arr) / count($arr);
После чего меня попросили написать через цикл, лол.
3 недели уже работаю.
Аноним 06/05/15 Срд 22:07:05 #458 №474623 
>>474622
Охуеть как просто. Что за город? Какие у тебя знания?
Аноним 06/05/15 Срд 22:27:32 #459 №474633 
14309404520450.png
>>474623
>>474623
Новосиб, ну учебник прорешал почти до кошек-мышек. С MySQL ковырялся, создавал гостевуху например. Далее по мелочи html и css, сейчас бутстрап немного знаю уже. Ну что еще могу сказать, до этого брался за несколько тестовых заданий на джуна в крутые конторы, но еще до знания ООП и mvc, писал кучу лапши и дропал от несовершенства и неуверенности в себе. Это кстати уже второй мой успех в устройстве на работу, первый раз взяли вообще нихуя не спросив по сути, а что спросили - то я ответил что не могу. Так что советую тебе делать больше попыток. Отсылать резюме и прочее говно. На выходных набыдлокодил вот http://serdce-kamnya.comeze.com раковую поделку для ХС-треда (если не знаком с игрой и мемсами, то покажется еще большей хуйней чем есть)
скрипт показывать пока что стыдно, внутри пиздец полный и мрак. Пока что ссессиями даже толком не разобрался и там дублируются куски кода через if,ы

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

А ну и да, я не >>474579 этот парень.
Аноним 06/05/15 Срд 22:45:34 #460 №474639 
>>474633

Эмм, а почему винрейт такой низкий и на курином ранге 5 звезд, а не 3?
Аноним 06/05/15 Срд 22:48:01 #461 №474645 
Парни, напрягитесь
class A {function callClassName() { return ???; }}
class B extends A {}
$b=new B;
echo $b->callClassName();
Что надо написать вместо ??? чтоб написало В?
При __CLASS__ пишет А
При get_class($this) пишет ничего и Warning: First parameter must either be an object or the name of an existing class in
Хотя var_dump(get_class($this)) пишет В
Аноним 06/05/15 Срд 22:51:05 #462 №474648 
>>474639
Везде по 5 звезд ради упрощения. Чем больше скилл, тем больше шанс на победу. Скидывай сезон и будет лучше винрейт в следующем.
Аноним 06/05/15 Срд 23:00:24 #463 №474656 
>>474633
Скинь ссылку на специалиста
Аноним 06/05/15 Срд 23:32:30 #464 №474666 
>>474656
Ну блин, ты точно собрался быть веб разработчиком, если не можешь гугл открыть?
https://www.google.ru/?gfe_rd=cr&ei=GE3DU837IpWEYMrlgbAL&gws_rd=ssl#newwindow=1&q=%D1%81%D0%BF%D0%B5%D1%86%D0%B8%D0%B0%D0%BB%D0%B8%D1%81%D1%82+php+2013+%D1%82%D0%BE%D1%80%D1%80%D0%B5%D0%BD%D1%82
Аноним 06/05/15 Срд 23:47:10 #465 №474673 
Анон, а в задачке про файлообменник лучше два класса сделать для загрузки и скачки файла(внутри них будет по одному экземпляру класса для работы с бд), или в один все объединить?
Аноним 07/05/15 Чтв 00:22:12 #466 №474694 
>>474673
Класс для работы с БД один имхо, а в нем два метода соответственно 1 для скачивания, второй для аплоада. Сам пока не делала, но имхо так бы сделал.

>>474645
http://ideone.com/1NBibJ
Хз в чем у тебя проблема, может ошибка в написании просто была?
Аноним 07/05/15 Чтв 00:31:28 #467 №474698 
>>473533
Идею поня, интересно, сейчас добиваю файлообменник, вроде бы немного понимаю как можно реализовать что ты говоришь, попробую что то написать.
Аноним 07/05/15 Чтв 01:08:16 #468 №474707 
Репорт ин. Кун, который работает на удаленку и пилит всякую поёбень для wp хочет перебраться в нормальную команду.

Предложили сделать 3 тестовых задания. Задания на алгоритмы. Я их сделаю(кстати, одно из них на поиск минимального пути в графе, так что делайте задачку про станции метро).

Но возникла проблема. Требуют, что бы код считывал с консоли значения чисел? Я нашел мануал, но есть ли с годными пояснениями для нубов? http://docstore.mik.ua/orelly/webprog/pcook/ch20_04.htm
Аноним 07/05/15 Чтв 02:15:21 #469 №474722 
>>474547

Надо добавлять в форму на самой страниц скрытое поле с id

> если всё успешно добавляется то делаю обратно перенаправленнее на страницу вывода поста
Вроде нормально. После успешной обработки пост запроса надо в любом случае делать редирект.

Вот мой урок про работу с формами: https://github.com/codedokode/pasta/blob/master/forms.md может там есть что полезное

>>474569

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

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

>>474579

Молодец! Пусть твой пост посрамит скептиков которые думают что у нас тут все несерьезно.

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

Аноним 07/05/15 Чтв 02:36:29 #470 №474726 
>>474613

Опечатка в переменной, смотри сообщения внизу.

>>474622

> После чего меня попросили написать через цикл
Они наверно не знали про array_sum и сами решали циклом :) Кстати прочти тогда и про функции array_column, array_map и array_count_values — они иногда тоже позволяют заменить цикл. Ну если ты решал задачу про Маяковского то наверно вспомнишь как max + array_map позволяют найти максимальную длину строки в массиве строк без циклов.

>>474673

Почитай сначала урок про работу с Бд. Я советую тебе как и другим сделать тут data mapper: https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md

И внимательно перечитай комментарии к задаче про студентов (ты ее пропустил? зря, зря), там много универсальных советов: https://github.com/codedokode/pasta/blob/master/student-list.md

>>474707

> требуют, что бы код считывал с консоли значения чисел?
Ты умеешь работать с файлами? В линукс (и в PHP как следствие) потоки ввода с клавитатуры и вывода на экран очень похожи на файлы и с ними можно работать теми же функциями: fwrite, fread, fgets, file_get_contents (почитай мануал по этим и по соседним с ними функциями, лучше весь раздел про работу с файлами)

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

Если ты этого не знаешь опять же полистай этот раздел: http://php.net/manual/ru/book.filesystem.php

Для потока ввода с консоли (то есть с клавиатуры) открывать ничего не надо. Он уже открыт и его дескриптор хранится в константе STDIN: http://php.net/manual/ru/features.commandline.io-streams.php

Заметь что он доступен только при запуске из консоли (что логично).

На тот случай если он не открыт, ты можешь просто передавать специальный путь php://stdin вместо имени файла. Это описано тут:

http://php.net/manual/ru/wrappers.php.php

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

Вот еще тебе гайд по командной строке: https://gist.github.com/codedokode/10539568

Ну и для тестирования тебе наверно надоест руками вводить исходные данные. Консоль позволяет автоматизировать это и перенаправить данные из файла на стандартный вход программы (то есть сделать вид что их ввел пользователь). Это делается так:

php program.php < file.txt

Описание перенаправления потоколв ввода вывода:

https://ru.wikipedia.org/wiki/%D0%9F%D0%B5%D1%80%D0%B5%D0%BD%D0%B0%D0%BF%D1%80%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B2%D0%B2%D0%BE%D0%B4%D0%B0-%D0%B2%D1%8B%D0%B2%D0%BE%D0%B4%D0%B0
Windows: http://geektimes.ru/post/60604/
http://cmcmsu.no-ip.info/1course/dos.io.redirect.htm
http://www.windowsfaq.ru/content/view/260/57/


linux: http://rus-linux.net/book1.php?name=book1/gl-05/gl_05_05.html
http://younglinux.info/book/export/html/214
http://xgu.ru/wiki/%D0%A1%D1%82%D0%B0%D0%BD%D0%B4%D0%B0%D1%80%D1%82%D0%BD%D1%8B%D0%B5_%D0%BF%D0%BE%D1%82%D0%BE%D0%BA%D0%B8_%D0%B2%D0%B2%D0%BE%D0%B4%D0%B0/%D0%B2%D1%8B%D0%B2%D0%BE%D0%B4%D0%B0

ОБрати внимание что потоков вывода два: стандартный вывод stdout и поток ошибок stderr. Это сделано чтобы ты мог сохранять результаты работы программы в один файл, а ошибки в другой или на консоль. Хорошая программа пишет ошиьки именно в поток ошибок (echo пишет в стандартный вывод и не подходит, нужен fwrite(STDERR, ...))

Эти знания тебе скорее всего еще пригодятся так что почитай.


Аноним 07/05/15 Чтв 02:38:57 #471 №474727 
>>474707

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

Также там не описана удобная функция fgets читающая одну строку из потока.

Аноним 07/05/15 Чтв 05:31:16 #472 №474737 
Ай нид хелп!!!
Ребята короче такая тема, надо создавать временный архив с набором файлов и в дальнейшем скачивать его с последующим удалением.
Генерацию архива реализую средствами пхп ZipArchive.
Но при $zip->addFile('C://[имя файла]); создается пустой архив, но с объемом не равным 0. Как пофиксить?
ЗЫ: $zip->addFile('[имя файла в корневой папке сайта]'); все ок
Аноним 07/05/15 Чтв 06:55:30 #473 №474746 
>>474737
Разобрался, нужно было добавить строку с выбором дерриктории
chdir
Аноним 07/05/15 Чтв 08:04:25 #474 №474754 
Числа прописью https://ideone.com/0ImLFa Джва дня делал.
Аноним 07/05/15 Чтв 08:26:15 #475 №474761 
>>474582

>>474722

Был на уровне задачи про файлообменик плюс я дропнул вышку кодера, начал разбираться с Yii и решил указать его на HH, мне сами позвали с вакансии где симфони и куда я вообще не подходил по моему мнению.
На собеседование были базовые вопросы и задачкa на взаимодействие с БД(как обработать постоянно добавляюшиеся строки ), немного JS. Все сделал.
Сказал что симфони не знаю, с йии мало знаком, но в итоге мне перезвонили.
Возможно это потому что я просил меньше денег чем было в этой вакансии на ХХ.
Но я в любом случае рад что попал не в битрикс контору, а вотвполне интересное место
Аноним 07/05/15 Чтв 09:28:37 #476 №474778 
>>474472
>Диванные оптимизаторы пожаловали в тред?
ага
Аноним 07/05/15 Чтв 09:30:33 #477 №474779 
Проверьте пожалуйста:
http://ideone.com/oDXszI
http://ideone.com/Eync0h
Аноним 07/05/15 Чтв 10:13:00 #478 №474783 
Оп, у тебя есть что читнуть по композеру? Идею я вроде понял, но так как виндоребенок, не особо дружу с командной строкой и даже установить толком не могу. То есть не пойму куда его надо ставить, сперва надо с помощью cd перейти в корень проекта и там уже запускать команду на скачивание? А потом composer.json руками создавать? А когда библиотеки скачиваешь надо 'находиться' в корне проекта или в vendors?
Аноним 07/05/15 Чтв 10:52:09 #479 №474807 
>>474779
И еще в догонку:
https://ideone.com/v3Zd7d
http://ideone.com/g8hcJU
Аноним 07/05/15 Чтв 11:50:11 #480 №474840 
>>474807
И еще: https://ideone.com/PSC6VW - в этой задаче не сделал исправление, слишком много надо дописывать регулярок (для каждой буквы свою же надо будет писать, да?).

Из всей тему про регулярки не понял только, как выделить все слово, в котором нашли нужную букву/часть. Как у тебя в примере выполнения задания про опечатки, ОП.
Аноним 07/05/15 Чтв 13:21:51 #481 №474895 
>>474761
>немного JS
О, спасибо за эту инфу, всё-таки на ПХП тоже надо яваскрипт, надо хоть немного подучить.
>на взаимодействие с БД(как обработать постоянно добавляюшиеся строки )
Вот тут немного не понял, в смысле обработать постоянно добавляющиеся строки?
Аноним 07/05/15 Чтв 14:16:56 #482 №474927 
14309974165340.jpg
>>474783
Скачиваешь:
https://getcomposer.org/download/
Устанавливаешь нужные вещи
https://packagist.or>>474727
>>474727
>>474726
Спасибо
Аноним 07/05/15 Чтв 14:54:54 #483 №474940 
>>474783

Статья на хабре: http://habrahabr.ru/post/145946/
Официальный подробный но англоязычный мануал: https://getcomposer.org/
Гайд по командой строке (советую прочесть): https://gist.github.com/codedokode/10539568

Установить можно инсталлятором который все сделает сам или (как я делаю) скачать с сайта composer.phar и запускать указывая путь к нему:

php d:/temp/composer.phar install

phar, если ты не знаком, это такой формат архива который содержит внутри php файлы и который php умеет распаковывать и запускать. Фактически это zip архив с файлами. Инстаяллятор устанавливает тебе этот phar и настраивает систему чтобы он запускался одной командой composer (он делает это добавляя файл composer.bat). Я не люблю инсталляторы и запускаю все вручную.

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

> сперва надо с помощью cd перейти в корень проекта и там уже запускать команду на скачивание?
да

> composer.json руками создавать?
быстрее наверно руками, но там есть команда require https://getcomposer.org/doc/03-cli.md#require которая добавляет имя библиотеки и версию в файл, то есть ты можешь использовать ее:

php composer.phar require vendor/package:2.×

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

Названия пакетов и номера версий можно посмотреть тут: https://packagist.org/ — это официальный репозиторий где хранится полный список. Набери например slim и увидишь подходящие пакеты. Согласись удобнее чем руками искать, скачивать архивы, распаковывать и тд.

Название пакета обычно состоит из 2 частей вроде slim/slim. Первое это ник автора на гитхабе или другом сервисе, второе это название проекта.

Когда ставишь версию, лучше не привязываться к однйо версии, а писать например
2.× — это значит любая версия начинающаяся с 2. Это позволит обновить библиотеку когда выйдет новая версия.

Когда привыкнешь пользоваться композером, тебе что-то руками скачивать расхочется, композер гораздо удобнее.
Аноним 07/05/15 Чтв 15:00:53 #484 №474942 
>>474783

> А когда библиотеки скачиваешь надо 'находиться' в корне проекта или в vendors?
В корне. В той же папке что и composer.json иначе он его не найдет.

>>474840

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

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

(граница слова)(любая буква от 0 до беск. раз) .... (любая буква от 0 до бесконеч. раз) (граница слова)

Если ты справа и слева припишешь такое, то регулярка найдет слово целиком. Граница слова это \\b — это выражение значит что с одной стороны от него должно быть буква, а с другой не быть буквы.

Есть удобный сайт чтобы применять регулярку к тексту и смотреть результат: https://regex101.com/

Если будешь им пользоваться помни что в «flavor» должно быть выбрано PCRE и что бекслеши тут не надо писать по 2 раза, то есть мы пишем в учебнике \\d, \\b а тут \d, \b

Соответственно на этом сайте ты можешь править регулярку и видеть каким частям текста она соответствует.

Аноним 07/05/15 Чтв 15:03:37 #485 №474945 
>>474840

По поводу регулярки: я думаю, тут лучше искать по-другому. В чем особенгость слов с опечатками? Главная особенность что там либо идет латинская буква после русской либо наобророт. Значит можно составить выражение:

граница-слова любые-буквы ( русская латинская ИЛИ латинская русская ) любые буквы граница-слова

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

Аноним 07/05/15 Чтв 15:09:56 #486 №474951 
>>474707

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

В ОС для этого есть специальный способ. В Windows ты жмешь F6 и Enter. В Линукс жмешь Ctrl + D (работает только если перед ним нажали Enter). Это говорит системе о том что ты ввел все хотел. Система закрывает поток ввода (больше ввести и передать программе уже ничего нельзя), а программа при чтении получает уведомление что файл прочитан целиком и закончился (это можно проверить например функцией feof). То есть цикл чтения по строчно может выглядеть так:

while (!feof($file)) {
$line = fgets($file);
}

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

Аналогично если ты читаешь данные целиком с помощью file_get_contents() то F6/Ctrl + D как раз скажет функции о том что в потоке больше нет данных и она остановится и вернет прочитанное.

Аноним 07/05/15 Чтв 15:23:57 #487 №474955 
>>474754

> if ($lastSymbol == 1) {
> $result = ' рубль.';
А работает ли это с числом 11? Нет:

https://ideone.com/j9bTqu
> Одиннадцать миллионов одиннадцать тысяча одиннадцать рубль. (11011011)

Числа 11-19 это исключение из общей системы.

Функция smallNumberToText($input, $isFemale) реально сложная. Там много кода и он выглядит запутанно. Я предлагаю упростить ее так:

— делаем пустой массив для слов
— если в числе есть сотни то добалвяем в массив нужные слова
— если в числе есть 10-19 то добавляем в массив слова
— иначе если в числе есть десятки то добавляем слова
— если есть единицы то добавляем слова

В конце объединяем массив в строку.

То же самое с функцией numberToText($input)

Пока в нынешнем виде код не годится даже если он правиьно работает, так как он слишком сложно написан и нереально потом его поддерживать/править и тд. Это можно и нужно сделать проще.

> Поменяем ключи и значения ключей местами, чтобы использовать функцию array_search
Это плохая идея так как ты можешь искать и в исходном массиве по ключу и поиск по ключу во много раз эффективнее array_search:

if (isset($a[$b])) или if (array_key_exists($a, $b))

Второй способ работает в 100% случаев, первый воспринимает NULL в массиве как отстутвие элемента и потому работает в 99% случаев. У тебя NULL нету так что он тоже сработает.

> $result = array_search($input, $flipped);
Чтобы взять элемент массива по ключу можно написать: $a[$b] — проходил ли ты урок про массивы? Если нет то почитай хотя бы начало, если да то плохо что у меня это не объясняется, я уже давно хочу улучшить этот урок, там конечно написано все довольно сумбурно.

> $singleDigits = mb_substr($input, 1, 1)
C числами надо работать математическими функциями, а не строчными. Это просто, вот 2 волшебных команды:

// получить последние 3 цифры числа:
echo 1234567 % 1000; // выведет 567

// получить число миллионов
echo floor(1234678 / 1000000); // выведет 12

Комбинируя их, можно получить что угодно.

> тысячь
граммар наци: мягкий знак не нужен

Аноним 07/05/15 Чтв 15:47:56 #488 №474964 
Оп-кун, а если нужен факториал, то стоит функцию самому написать, правда?
Аноним 07/05/15 Чтв 16:11:14 #489 №474974 
>>474964

Если она тебя устраивает по времени работы то да. Но помни что факториал быстро растет и для больших чисел банально точности не хватит, результаты будут приближенные и может быть не совсем точные. Если у тебя серьезная математика/физика лучше погуглить и поискать хорошие алгоритмы.
Аноним 07/05/15 Чтв 16:13:46 #490 №474976 
>>474974
У меня O(n) сложность вычесления. Вообще да, хватает потому, что для очень больших чисел php уже не умещает в памяти это число.
Аноним 07/05/15 Чтв 16:21:12 #491 №474980 
Оп, можешь глянуть решение для задачки про деревья из https://github.com/codedokode/pasta/blob/master/interview-tasks.md , пожалуйста?
http://ideone.com/5i21ND
Аноним 07/05/15 Чтв 16:24:40 #492 №474982 
>>474976

Не, все хитрее:

— есть небольшие целые числа, для 32 битной системы предел +- 2 млрд, для 64 битной 2 млрд в квадрате. Они хранятся точно. Это int.

— есть большие числа, от 2 млрд до 10 в 38-й (в 64 битной системе до 10 в 308-й степени). Эти числа хранятся неточно, сохраняя 7 или 14 знаков после запятой (а также есть бибиотеки которые дают большую точность). Это float.

— есть огромные числа и их стандартно php хранить не может (но есть библиотеки которые могут)

Подробнее про приближенные числа можно прочесть например тут: http://habrahabr.ru/post/112953/

Если нужна работа с огромными числами или высокая точность то в PHP есть расширения

http://php.net/manual/ru/book.gmp.php
http://php.net/manual/ru/book.bc.php

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

Может ты все это знаешь, тогда может этот пост еще кому-то пригодится.
Аноним 07/05/15 Чтв 16:29:53 #493 №474984 
>>474982
Спасибо. Я летом думал RSA реализовать, думаю пригодиться.
Аноним 07/05/15 Чтв 16:52:15 #494 №474994 
>>474980

Ты как-то переусложнил код по моему. Тут можно сделать гораздо проще.

Начнем с ООП реализации. Ты сделал один объект который представляет дерево, а внутри него куча массивов. Чувствуешь что это не совсем ООП, а попытка засунуть процедурный код с массивами внутри объекта? Ты просто взял список функций, написал вокруг них class X { ... }. Это не полноценное ООП-представление для дерева.

Ну вот недостаток твоего дерева. Как известно, в дереве, если мы возьмем какую-то ветвь то это фактически тоже дерево. Получается эта ветка должна тоже быть объектом класса Tree. У тебя ты не можешь получить ветку в виде объекта Tree.

Дерево лучше реализовать по-другому. Ты делаешь класс который представляет собой один узел (Node), у которого может быть родитель и дети. Вот и получилось дерево. Осталось написать несколько методов которые например при добавлении ребенка будут автоматически проставлять ему parent:

$parent = new Node;
$child = new Node;
$parent->addChild($child); // автоматически проставляет parent у ребенка

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

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

Фактически ключевая часть твоего алгоритма это buildAdjacencyList($template). Возьми эту функцию, допиши вторую функцию которая берет adjacency list + исходный массив и рекурсивно выводит дерево — и задача решена.

В общем мое мнение: алогритм можно сделать либо проще и без ООП, либо с нормальной реализацией ООП-дерева.
Аноним 07/05/15 Чтв 16:55:37 #495 №474997 
Опчик, как на счет сделать беседу в вк для удобства?
Аноним 07/05/15 Чтв 17:12:59 #496 №475006 
>>474997

Проясни свою мысль, как именно? Если речь о группе то мне конечно нравится идея создать что-то вроде группы вконтакте так как это позволит расширить аудиторию (ибо я чувствую что на бордах мы уже выбираем всю доступную аудиторию и больше ее тут нет), но мне же круглостуточно там придется сидеть всем отвечать.
Аноним 07/05/15 Чтв 17:13:59 #497 №475007 
>>474997

Алсо я негативно отношусь к сервисам которые требуют телефон для регистрации. Неужели Дуров жить без моего номера телефона не может?
Аноним 07/05/15 Чтв 17:17:49 #498 №475008 
>>475006
ну, например, ты можешь вести курсы в хенгауте или трансляцией на ютуб.
Группу создавать не обязательно, можно просто беседу, что бы там общаться. Там, я думаю, будет как-то живее. Тред вялый, имхо. В беседе еще можно устраивать всякие квесты.
Можно и группу создать, но это более геморно.
Аноним 07/05/15 Чтв 17:18:56 #499 №475011 
>>474895

У меня, как то вылетело из головы точное содержание, но суть была в то что есть таблица и в неё регулярно добавляются новые строки(заявки какие нибудь на сайте оставляют например), нужна была функция которая следит за обновлениями таблицы и обрабатывает новые строки, любой другой функцией например
Аноним 07/05/15 Чтв 17:18:59 #500 №475012 
>>475007
есть сервисы, где можно на день взять сим в аренду. Для регистрации хватит.
Аноним 07/05/15 Чтв 17:19:32 #501 №475013 
>>475007
ФСБ требует же.
Аноним 07/05/15 Чтв 17:25:01 #502 №475016 
>>475008

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

Хотя все конечно зависит от реализации, я видел видеокурсы от западных университетов (не про PHP), они довольно хорошие. Там кстати сами видеоролики были довольно короткие и после небольших объяснений сразу же дают задачу, пока ты не забыл материал.

Ну и в плане производства наверно это труднее.
Аноним 07/05/15 Чтв 17:27:12 #503 №475019 
>>475016

В тех видеокурсах кстати показывали лектора и формулы, а не экран (это по моему был курс по искуственному интеллекту и всяким связанным темам вроде вероятностей, байесовского фильтра и тд). То есть это не курсы уровня «перепечтаывайте мой код».
Аноним 07/05/15 Чтв 17:27:42 #504 №475020 
>>475012

Это значит что твой аккаунт может быть угнан в любой момент.
Аноним 07/05/15 Чтв 17:28:03 #505 №475021 
>>475016
ты знаешь, что такое хенгаут? там есть живой фидбек, каждый может в ту же минуту спросить, что он не понял. По-моему, идея хорошая. Тред не удобен.
Аноним 07/05/15 Чтв 17:30:43 #506 №475023 
>>475013

У хабра, гитхаба, твиттера и фейсбука видимо оно требовать не осмеливается? Я помню, были (довольно убедительные) аргументы про то что это помогает бороться со спамом (спама раньше и правда было довольно много, я помню), но недавно я задал себе вопрос: а как же тогда другие соцсети с большим числом пользователей умудряются жить без привязки к телефону?
Аноним 07/05/15 Чтв 17:38:38 #507 №475026 
>>475012
Позырьте на ютабе урок от школьников как зарегать акк на малазийский фейкономер, я так сделал, зависимость есть.
Аноним 07/05/15 Чтв 17:43:20 #508 №475028 
>>475021

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

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

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

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

В любом случае, спасибо за предложения, я всегда рад услышать замечания и обратную связь, я понимаю что нынешняя система не идеальна, но что касается их реализации, тут приходится считаться с возможностями и ограничениями. Мне надо как-то доносить знания максимальному числу людей с минимальными затратами времени.
Аноним 07/05/15 Чтв 17:44:30 #509 №475029 
>>475026

Ага, а украинским анонам как я понимаю еще проще, там вообще без паспорта сим карты продают.
Аноним 07/05/15 Чтв 17:51:05 #510 №475036 
>>475028
Ну беседу все равно можно запилить, хотя бы для общения анонов между собой на тему пхп.
Аноним 07/05/15 Чтв 17:54:01 #511 №475040 
>>475036
>вк
>анонов
Аноним 07/05/15 Чтв 18:07:44 #512 №475052 
Зачем вк? Завели бы телеграм.
Есть на всех платформах, удобнее и всё такое.
Аноним 07/05/15 Чтв 18:29:47 #513 №475067 
>>475052

Дуров, залогиньтесь уже.

Аноним 07/05/15 Чтв 19:07:23 #514 №475091 
Пацаны, делаю пагинацию типа так:
define(ITEMS_PER_PAGE, 10); /где-то в конфиге/;
<?php
$arr = array('php' , 'mysql', 'html', 'css', 'javascript'); /чисто для примера. может быть массивом результата запроса к базе/
$page_num = ceil(count($arr)/ITEMS_PER_PAGE);
for($i=1; $i<=$page_num; $i++) :
?>
<a href = "<?='blabla.php?page='.$i; ?>"><?=$i; ?></a>
<? endfor; ?>
А то я смотрю уроки на ютабе там городят специальный класс Пагинатион который тоже самое делает, только смысла я не вижу получается только сложнее имхо.
Аноним 07/05/15 Чтв 19:30:43 #515 №475109 
Делаю файлообменик, и реализовал его таким образом что форму загрузки файла выполняет одна страница, которая в случае правильной загрузки перенаправляет обратно на страницу где есть эта форма и выводит ссылка на скачивание. Всё вроде бы норм, когда дело касается картинок и текстовых файлов, то есть файлов небольшого размера, но когда речь идёт уже о аудифайлов то просто ничего не происходит. Вот метод реализовывающий загрузку:

public function upload($upload) {

$url = 'files/'.$upload->name;
if(move_uploaded_file($upload->tmp, $url)) {

if($stmt = $this->db->prepare("INSERT INTO `bulletin`.`files` (`id`, `name`, `size`, `type`, `time`, `comment`, `url`) VALUES (NULL, ?, ?, ?, NULL, ?, ?)")) {
$stmt->execute(array($upload->name, $upload->size, $upload->type, $upload->comment, $url));
$id = $this->db->lastInsertId();
setcookie('id', $id);
return true;
}
}
else false;
}

Как я пытался проверять не срабатывает вот этот кусок:

if(move_uploaded_file($upload->tmp, $url))
Аноним 07/05/15 Чтв 19:34:12 #516 №475116 
>>475109
Извините котаны, только что вспомнил про error при загрузке файла, всё прояснилось.
Аноним 07/05/15 Чтв 19:58:29 #517 №475126 
Что делать аноны? Есть две библиотеки которые я подключая к странице, одна:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>

Отвечает за модальные окна, которые нужны на этой странице, другая:

<script src="http://osvaldas.info/examples/audio-player-responsive-and-touch-friendly/audioplayer.min.js"></script>

Аудиопроигрыватель, если подключена так которая отвечает за модальные окна, криво работает та которая отвечает за аудиопроигрыватель, на странице нужно и то и то.
Аноним 07/05/15 Чтв 20:15:51 #518 №475130 
Оп, помоги, я учил пхп, но забросил около месяца назад. И теперь не помню на чем закончил и с чего взяться опять.
Аноним 07/05/15 Чтв 20:32:30 #519 №475135 
>>475126
Яничегонепонял. Первый скрипт - это jquery, а не 'модальные окна'. Его используют многие сторонние скрипты, скорее всего, и твои 'модальные окна' тоже, но они опять же, скорее всего, реализованы в другом скрипте.
Твой аудиоплеер тоже требует jquery и по идее вообще не должен без него работать, а не конфликтовать как ты пишешь.
Олсо, ты какую-то старую версию подрубаешь.
Аноним 07/05/15 Чтв 20:36:45 #520 №475139 
>>475126

Подключая скрипты с какого-то малоизвестного домена

> osvaldas.info

Ты дождешься того, что владелец заблокирует тебя по реферреру, его сайт ляжет, он его забросит и тд и точно также ляжет твой сайт. Не подключай скрипты со сторонних доменов особенно если они явно это не разрешают.
Аноним 07/05/15 Чтв 20:37:31 #521 №475140 
>>475130

Решай все задачи с начала. Если у тебя есть знания то ты будешь задачи щелкать как семечки, если нет хороший повод почитать уроки.
Аноним 07/05/15 Чтв 21:19:02 #522 №475158 
14310227425610.jpg
Сап, пыханы. Видимо мне к вам.
Есть один hostinger.ru и один db4free.net
Мне нужен мускуль с внешним доступом, который используется крайне редко, но без него никак. db4free медленная и глючная хуйня и вообще с ним постоянно какие-то проблемы, а на Хостингере внешний доступ платный, а мне жалко денег.
В общем думаю изредка пиздить данные из db4free на Хостингер. Надо просто иногда брать данные оттуда и засовывать сюда. Там по сути-то всего одна таблица.
Как такое реализовать пыхо-скриптом?
Аноним 07/05/15 Чтв 23:18:56 #523 №475212 
Есть такая вещь, есть форма с данными, её обрабатывает другой файл, в методе который её обрабатывает записываю в данные в базу данных, после этого записываю в куки последний ID полученный через вот это

db->lastInsertId()

На странице которая обрабатывает форму делаю следующий редирект:

if($mapper->upload($upload)) {
$id=$_COOKIE["id"];
header("Location: onefile.php?id=$id");
}

То есть вытаскиваю id из куки и передаю его в качестве параметра, в итоге на странице куда делается редирект id которое записано в куки на один меньше чем то id которое получено через метод GET, почему так?
Аноним 07/05/15 Чтв 23:37:33 #524 №475222 
>>475212

Поставь echo/var_dump во всех критичных местах (где читается кука, где ставится кука, где вызывается lastInsertId). Автоматический редирект тоже замени на echo чтобы переход делался вручную. Может быть это даст тебе ответ, может нет, если нет то напиши тут результаты.
Аноним 08/05/15 Птн 01:53:22 #525 №475275 
>>474779

задача про номера

По регулярке:

> ([+] 7|[+]7|
Это можно записать короче как [+]\\s?7

> [(]|[)]|-|
Если у тебя тут «один из этих символов» то проще использовать квадратные скобки: [abcd]

> \\d$
Что если в конце номера есть лишний пробел? Надо либо отрезать его с помощью trim() либо предусмотреть это в регулярке.

> preg_replace($regexpTwo, '', $result);
В данном случае регулярка маленькая и удобнее ее вписать прямо в эту строку без использования переменной. Ну и старайся не делать названия вроде regexpTwo так как оно ничего не говорит. Лучше назвать например regexpToRemoveNonNumbers (да, длинно, но зато понятно).

Мелкие замечания:

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

Аноним 08/05/15 Птн 02:01:52 #526 №475277 
>>474779

автозамена

Тут лучше использовать foreach вместо for. Вместо (a|b) удобнее писать [ab]. В остальном все верно.

>>474807

Поиск email

надо было конечно сделать нормально вывод email, по 1 на строчке например, а не вываливать так кучу строк включая куски email. Регулярка правильная.

Граммар наци

А программу которая пишет где и какая ошибка, ты не сделал? Надо бы сделать.

> '/(сдесь)/';
Тут скобки не нужны. зато нужен флаг u без которого регулярка может глючить на русских буквах. Ну и флаг i не помешал бы, а то слово с первой большой буквой не найдет.









Аноним 08/05/15 Птн 11:43:26 #527 №475375 
Поцаны, поясните мне за форматирование? Каких стандартов придерживаться? Хули везде все так ебано и по разному даже в мануалах на pp.net
Ну ладно
между и скобками я буду ставить пробел
if ($a) { - ok
if($b) { - fail
Так же с for () {

А как быть с функциями и классами? Хули везде поразному с выставлением фигурных скобок?

Сюда вот смотрю: http://php.net/manual/en/language.oop5.decon.php
И там пиздец, в одном месте:
class BaseClass {
     function __construct() {
          print "In BaseClass constructor\n";
     }
}

В другом:

class A
{
    function __construct()
    {

Они там что совсем поохуевали? Как они смеют так делать?
Аноним 08/05/15 Птн 12:33:24 #528 №475389 
>>475375

Лучше всего смотреть на стандарты PSR-1/2. Их придерживается большинство авторов современных фреймворков и CMS. Ты можешь посмотреть примеры кода и описание тут:

http://www.php-fig.org/psr/psr-1/ru/
http://www.php-fig.org/psr/psr-2/ru/

> и по разному даже в мануалах на pp.net
Исторически стандарта оформления не было (как в Си) и все писали как хотели. Но относительно недавно разработчики ведущих фреймворков объединились и смогли принять стандарты оформления кода. В принципе они похожи на более ранние стандарты Zend и PEAR и если ты им следовал то для тебя почти ничего не поменяется.

Соответственно некоторые примеры в мануале могли быть написаны до принятия сообществом этих стандартов.

> между и скобками я буду ставить пробел
Да

> А как быть с функциями и классами?
Скобка на новой строке

class A
{

}

function b()
{

}



Аноним 08/05/15 Птн 12:49:13 #529 №475396 
>>474310

> Пример $conditions: ['friendlist' => ' LIMIT 10', 'playlist' => ' AND genre = jazz' ]
Вот это кстати плохая идея так как тут нет подстановки параметров и мы можем словить SQL инъекцию:

$conditions = ['playlist' => "AND genre = '$genre'"]; // упс, инъекция

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

['genre' => 'jazz']
['genre' => $genre]

Тут код знает что справа может быть что угодно и корректно экранирует это.

А для limit сделать отдельный параметр.

>>474633

> его учебник не сделает из вас специалистов, нужно дохуя еще чего читать.
Это наверно так и есть, но ведь ты прошел только учебник, а там еще есть задачи после учебника, на список студентов и файлообменник, которые учат работать с базой, с формами, и т.д (ну то есть как учат, объясняют в общих чертах, а дальше сам читай статьи и мануалы). Мне кажется с ними знания получаются вполне достаточные. Что полезного есть в курсах специалиста, чего нет у нас? Я их не смотрел потому сам не знаю.

Аноним 08/05/15 Птн 12:56:38 #530 №475398 
>>475091

У этого метода есть недостаток: этот код неуниверсален и привязан к конкретному URL ( blabla.php, ITEMS_PER_PAGE ). Ты не можешь применит его для другой таблицы без изменений, придется копипастит, а копипаста это зло.

Также ты выводишь ссылки на все страницы, а что если надо сделать так:

Первая | ... | 3 | 4 | 5 | 6 | 7 | ... | Последняя

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

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

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

Аноним 08/05/15 Птн 13:00:21 #531 №475399 
>>475109

> Как я пытался проверять не срабатывает вот этот кусок:
Надо при ошибке выводить соотв. сообщение и предлагать загрузить файл еще раз (если конечно это не ошибка превышения размера).

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

https://php.net/manual/ru/features.file-upload.errors.php
https://php.net/manual/ru/features.file-upload.post-method.php

>>475126

Конкретную причину надо искать отладчиком, может он в консоль пишет текст ошибки, может нет. Отладчик открывается через Ctrl + Shift + I в браузере.

Чтобы полноценно решить эту проблему нужно знание яваскрипта разумеется.

Статья про отладчик: http://habrahabr.ru/post/143767/
Аноним 08/05/15 Птн 13:03:08 #532 №475400 
>>475158

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

> Как такое реализовать пыхо-скриптом?
Не понял смысл вопроса? Тебе надо чтобы скрипт написали? Это маловероятно.
ОП 08/05/15 Птн 13:03:39 #533 №475401 
Если я кого-то пропустил, напомните о себе.
Pashteto 08/05/15 Птн 14:40:45 #534 №475428 
Привет ОП. Я уже учился под твоим руководством, но дропнул на файлообменнике из-за битардского характера. Сейчас постараюсь заниматься регулярно и доучиться до приемлемого уровня. У меня есть пару вопросов:
- Какие задачи посоветуешь перерешать из учебника?
- Видел большую копипасту про установку Debian на виртуальную машину в старых тредах, где можно ее посмотреть? Если пропала, то какой фтп сервер лучше ставить? Чем редактировать конфиги в консоли, а то vi уж больно хардкорен.
- Как вообще обустроена рабочая среда у профессионалов? Все сидят на линуксах с копией проекта на локальном веб сервере / держат виртуальные машины / в сети есть сервер для отладки, где все стоит ? Вот у меня сейчас все в виртуальной машине, кроме phpstorm, не слишком ли это пердолинг?
Аноним 08/05/15 Птн 15:45:51 #535 №475452 
>>475428

> Какие задачи посоветуешь перерешать из учебника?
Никакие. Решай задачу про список студентов если не решал, и фйлообменник, а потом к Yii 2 переходи.

> редактировать конфиги в консоли,
nano очень простой, mcedit тоже довольно несложный, но более мощный

> какой фтп сервер лучше ставить?
Не надо. Если у тебя есть ssh-доступ то можно закачивать файлы по SFTP (он вдобавок в отличие от FTP шифрует все данные). Программами типа WinSCP например.

Я обычно пишу bash скрипт для таких вещей, чтобы руками ничего не делать, а просто запустил скрипт и он сам закачивает изменившиеся файлы. Для этого команда rsync может использоваться в простейшем случае. В принципе там даже можно сделать чтобы он сам обнаруживал изменения и автоматически их синхронизировал, но мне кажется это будет нагружать процессор сильнее.

> Все сидят на линуксах с копией проекта на локальном веб сервере /
Вообще по-разному, кто к чему привык тот тем и пользуется. Еще маки популярны. Я например Windows использую, для линукса есть виртуалка.
Лучше всего когда нет привязки к конкретной платформе и софту.

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

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

Вот к примеру гифки некоторых возможностей Sublime: http://www.sublimetext.com/ — в PhpStorm подобных вещей должно быть еще больше. IDE это твой инструмент и его надо знать в совершенстве, а не использовать как блокнот с подсветкой.

Все рутинные вещи (вроде закачки файлов на сервер) надо стараться автоматизировать, чтобы они не тратили твое время.

git и composer надо освоить если еще не освоил.

> в сети есть сервер для отладки, где все стоит
Бывает и такое но если с ним что-то случится, работа останавливается.

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

> Вот у меня сейчас все в виртуальной машине, кроме phpstorm, не слишком ли это пердолинг?
Нет. Хотя если проект простой по моему удобнее его без виртуалки запускать, но это не всегда возможно, конечно. Раньше многие использовали виндоуз/MySQL и проекты работали везде, а сейчас конечно делают как попало.

Гайд по командной строке https://gist.github.com/codedokode/10539568

Вот собрал старые посты по виртуалбоксу и дебиану: https://gist.github.com/codedokode/420c8c12a1edae25f0ec



Аноним 08/05/15 Птн 17:03:54 #536 №475488 
>>474955
Полностью переделал http://ideone.com/v2PbN4
Аноним 08/05/15 Птн 19:30:34 #537 №475564 
Оп, начал тут файлообменник делать. Приблизительно так нужно?
github.com/AzerusEncole/File_Sharing
Аноним 08/05/15 Птн 19:37:40 #538 №475565 
>>475564

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

Первый вариант решения проблемы это сделать папку, например 3rd-party и перенести в нее Слим, чтобы он был установлен примерно так:

3rd-party
---slim
-------.gitignore
-------composer.json
-------Slim


То есть внутри своей отдельной папки 3rd-party/slim

Второй, более хороший вариант это не устанавливать Слим руками вообще, а использовать композер. Композер это менеджер библиотек для php, то есть штука которая умеет сама их скачивать и устанавливать в отдельную папку (vendor). Ты создаешь специальный файл composer.json где описываешь какие библиоетки и каких версий тебе нужны, запускаешь композер и он сам их скачивает в папку vendor. при этом в репозиторий ты эту папку не коммитишь и в репозитории на гитхабе лежит только твой код.

Я советую освоить композер. Его используют везде.

Вот выше пост про него: >>474940

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

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

Аноним 08/05/15 Птн 19:43:49 #539 №475569 
>>475564

3rd-party (third-party) значит «сторонний», если что. Композер для сторонних библиотек использует папку vendor (что переводится как поставщик). Тут главное что весь сторонний код лежит в отдельной папке.

Еще, данные для соединения с БД надо вынести в отдельный файл, например config.php где должны быть только настройки и ничего более. Он может выглядеть например так:

$dbUser = 'root';
$dbPass = '123';

или использовать возможности Слима:

$app->config('db.user', 'root');
$app->config('db.pass', '123');

Главное чтобы это было в отдельном файле и я мог поменять настройки на свои. Также, приложи SQL дамп твоей базы. В нем не должно быть команд создания самой базы CREATE DATABASE или выдачи прав пользователю GRANT, только команды CREATE TABLE и INSERT.

Аноним 08/05/15 Птн 20:46:19 #540 №475592 
>>475565
Если в phpstorme создавать composer проект, можно один какой-нибудь пакет загрузить, прямо при создании. Он почему-то вне vendor'а сохраняется. А если просто загружать их по ходу - все нормально.
Аноним 08/05/15 Птн 21:01:44 #541 №475603 
>>475592

Скорее всего дело либо в странных настройках либо ты не так понял что делает та или иная команда phpStorm. Я советую сначала научиться работать напрямую с композером из командной строки, потом с оберткой над ним из PhpStorm.

Возможно ты сделал вот это: https://www.jetbrains.com/phpstorm/help/using-composer-dependency-manager.html#d288366e669

Это явно не то, что требуется (хотя из их мануала я сам не понял что это такое).
Аноним 08/05/15 Птн 21:19:05 #542 №475617 
Оп,кун, что будут спрашивать, если я указал в резюме, php, mysql/sql, html,css, jquery, git?
Аноним 08/05/15 Птн 21:19:23 #543 №475618 
>>475617
На интервью конечно же
Аноним 08/05/15 Птн 21:22:59 #544 №475620 
>>475617

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

По PHP советую полистать мануал, некоторые любят задавать всякие вопросы по особенностям php.

По MySQL любят спрашивать общие концепции вроде: нормализация, транзакции, внешние ключи, попросят написать какой-нибудь запрос с джойнами/группировкой.

Меня бы насторожило что ты написал jQuery но не написал JS. То есть яваскрипт (а соответственно и jQuery) ты не знаешь?

Аноним 08/05/15 Птн 22:12:44 #545 №475662 
>>475620
JavaScript я почти не использую и знаю его плохо, сейчас судорожно перечитываю мануал, интервью во вторник. по sql повторить кратко, что можно? особенно по нормализации, транзакции, внешних ключах, индексах(и почему поиск по индексах быстрее(слышал как задают этот вопрос, когда говорят что с индексами быстрее)).
Аноним 08/05/15 Птн 22:35:10 #546 №475667 
>>475620
ну то есть, я знаю про замыкания, я знаю синтаксис языка, но чисто на js почти не пишу. всегда обхожусь jquery. вот так.
Аноним 09/05/15 Суб 17:46:59 #547 №475989 
>>475617
Давно кодишь? Отпиши потом как прошло.
Аноним 09/05/15 Суб 19:33:03 #548 №476018 
бампану годный тред
Аноним 09/05/15 Суб 20:29:40 #549 №476037 
>>475662

Про индексы придется почитать ссылки отсюда:

https://gist.github.com/codedokode/10539213#%D0%98%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D1%8B

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

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

> по нормализации
Это важная тема которую надо знать при проектировании БД:

http://habrahabr.ru/post/193756/
http://webadequate.ru/rabota-s-bd-mysql/15-normalizaciya-obektov-v-mysql.html
http://i-novice.net/6-normalnyx-form-bd/

> внешние ключи и связи
http://denis.in.ua/foreign-keys-in-mysql.htm
http://jtest.ru/bazyi-dannyix/sql-dlya-nachinayushhix-chast-3.html


ОП 09/05/15 Суб 21:15:02 #550 №476060 
Аноны-хаскеллисты, смотрите, тут люди на вашем хаскелле хотят делать микросхемы (хаскелл конвертируется в VHDL): http://www.clash-lang.org/

Аноним 09/05/15 Суб 21:47:02 #551 №476073 
Поменял логику игры - теперь вместо поля-массива, поле сетки координат. Учел замечания по поводу дублирования данных и убрал из свойств классов слишком динамичные данные. Вот, что получилось:
http://ideone.com/01xYDL
Заранее спасибо!
Аноним 09/05/15 Суб 21:49:26 #552 №476075 
Кстати ОП, может перекатишь учебник на Github Pages? Там никакой рекламы нет, странно что учебник не там еще, ты ведь гитхабом пользуешься. А с народа редирект поставишь.
Аноним 10/05/15 Вск 01:13:23 #553 №476168 
>>475488

> if (($input >= 11) && ($input <= 14)) {
> $result = $word5;
лучше наверно сразу писать return $word5 чтобы было видно что функция в этом месте завершается и не надо было смотреть куда потом идет эта переменная.

Заодно можно будет убрать большой else.

> if ($input == 0) {
> $text[] = $spelling[$input];
В этом месте наверно лучше сразу возвращать строку «ноль» через return, так как дальше все равно к нему ничего нельзя дописать.

Сумму ноль программа не выводит: http://ideone.com/iaaxDV

> На вашем счету: (0)
Проще всего для нее там сделать отдельный if + return.

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

Аноним 10/05/15 Вск 01:54:24 #554 №476187 
>>476073

> protected $xPoint;
Можно просто $x для краткости. Можно и как у тебя, впрочем.

> public function getPosition()
По моему это неудобно и удобнее иметь 2 метода getX и getY, хотя я в этом не уверен. Если ты используешь массив, то удобнее наверно называть элемент 'x' и 'y', хотя тут я тоже не уверен.

> public function getLabel()
> {
> return $this->label;
Ты в классе Animal обращаешься к полю которого в нем нет. Такого быть не должно и класс ничего не должен знать о своих потомках.

Тут надо просто сделать абстрактный метод:

abstract public function getLabel( );

и переопределить его в потомках.

> if($this->xPoint !== $this->field->getSize()
В таких сравнениях лучше писать «меньше», код будет надежнее.

Ну и саму функцию наверно проще было записать как-то так:

$offsets = [[-1, 0], [0, 1], ...]; // возможные смещения
foreach ($offsets as $offset) {
Если (клеточка с такими координатами существует) {
добавить ее в список ;
}

это позволило бы объединить и упростить код функций findOrthogonalSteps и findDiagonalSteps. Мне кажется надо просто в field сделать метод проверяющий существует ли клетка с указанными координатами.

> protected function findNearestEnemy(array $enemies)
> return $enemiesPrices[min(array_keys($enemiesPrices))];
А что если массив пуст? эта строка выдаст ошибку.


> if(in_array($animal->getPosition(), $availableSteps)) {
ты сравниваешь массивы через in_array. Теперь вопрос тебе, а как работает сравнение в этом случае: сравниваются только значения в массивах или значения вместе с ключами?

[1, 2] == [2, 1] ?

Описано тут: http://php.net/manual/ru/language.operators.array.php

И мне кажется, этот код надо перенести в карту и сделать метод вроде «занята ли клеточка» или «получить животное на клеточке». это явно должно быть не в Animal.

> if(in_array($animal->getPosition(), $availableSteps)) {
> $key = array_search($animal->getPosition(), $availableSteps, true);
> unset($availableSteps[$key]);
Тут проще не удалять ничего, а сделать новый массив и добавлять в него только хорошие ходы.

> protected function setPricesOfSteps(Animal $nearestEnemy, array $allys, array $dogs)
> $pricesOfSteps[$price] = $step;
при таком подходе ходы с одинаковым числом очков затирают друг друга. Ну и способ хранения очков и координат странный и запутанный. Я бы хранил примерно так:

['x' => 9, 'y' => 8, 'price' => 100]

Или вообще можно завести класс из 3 свойств для этого (можно и массивом впрочем).

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

> protected function setPricesOfSteps(Animal $nearestEnemy, array $allys, array $dogs)
> $availableSteps = $this->findAvailableSteps($allys, $dogs);
Обращаешься к функции которой нет в Animal.

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

> $availableSteps = $this->excludeClosedPositions(array_merge($mouses, $dogs), $availableSteps);
Непонятно почему кошки не исключены, мышка может ходить по кошкам?

> private function findVisibleField($size)
Это должно быть в карте, а не в мыши, так как это относится к работе с картой. Более того, мне кажется незачем делать этот огромный массив клеток. Проще отфильтровывать животных при поиске их на карте:

кошки = $field->найтиВсехЖивотныхВРадиусе(кошки, 4, 5, 6);

Тогда и функцию checkProtection(array $mouses) можно написать с использованием этого же метода.

Ну и в самой мышке (а можно даже в Animal c переопределением в разных животных) можно сделать метод вроде получитьВсехЖивотныхКоторыхЯВижу().

> if($counter >= 2) {
> $this->isProtected = true;
Не уверен что isProtected должно быть свойством, а не обычной переменной. Оно же устаревает каждый ход, а ты его хранишь и можно подумать что оно всегда актуально. И эту ошибку потом ведь не найти будет в коде. Я думаю, это не должно быть свойством так как никто не поддерживает его в актуальном состоянии.

> if($visibleCats) {
> } else {
Мне кажется алгоритм выбора хода можно сделать единый независимо от того видны кошки или нет. Это сделает оценку ходов более разнообразной, так как она будет учитывать не только расстояние до кошек но и другие факторы работающие при одинаковом расстоянии.

> $position = $pricesOfSteps[min(array_keys($pricesOfSteps))];
> $this->xPoint = $position[0];
> $this->yPoint = $position[1];
это скопипастено несколько раз. Надо сделать метод «выбрать лучший ход».

> if($position === $nearestEnemy->getPosition()) {
> $nearestEnemy->setState(false);
Что значит «setState»? Съесть? Название абсолютно ничего не значит и не помогает. Ну и сделать это наверно надо по-другому, например:

карта->убратьЖивотное(мышка)

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

Методы makeStep, мне кажется, в разных животных, можно как-то обобщить. Они очень похожие.

> private function drawSchema()
> $key = array_search($animal->getPosition(), $schema, true);
Ты как-то тут все переусложнил. Тут достаточно сначала создать 2-мерный массив пустых клеточек, а потом пройтись по животным и сделать:

$map[$a->getX()][$a->getY()] = $a->getlabel( );

После чего преобразовать ее в строку implode в цикле.

> public function getAnimalsByType($animalType)
Тут наверно короче написать с использованием array_filter и анонимной функции.

В общем, пока код какой-то сложный и надо посмотреть как его можно упростить. Мне довольно сложно было его читать. Хорошо, что программа работает, но из-за ее сложности в ней могут быть баги (ну например кошки идущие к уже съеденной мышке).


Аноним 10/05/15 Вск 01:55:23 #555 №476188 
>>476075

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

Аноним 10/05/15 Вск 12:04:31 #556 №476255 
Оп, а если нужно дописывать говно-код на wp, что думаешь, стоит писать нормально или уже просто допилить?
Аноним 10/05/15 Вск 12:58:30 #557 №476265 
Есть форма взаимодействующая с WebMerchant сервисом от Вебмани, вот faq https://merchant.webmoney.ru/conf/guide_simple.asp

Пользователь вводит сумму, нажимает отправить и его редиректит на сайт вебмани, где собственно и осуществляется оплата. Так вот, я хочу, чтобы факт оплаты сохранялся на сайте (что-то вроде копилки), но проблема в том, что, как я уже сказал ранее, оплата осуществляется на сайте вебмани, а он уже редиректит на странички succes.html или fail.html в зависимости от результата. Допустим я хочу добавлять в таблицу факт и сумму выплаты, но при отправке формы я этого сделать не могу, так как в дальнейшем пользователь может отказаться от оплаты. Существует ли способ осуществить задуманное или с WebMerchant это невозможно?
Аноним 10/05/15 Вск 13:45:29 #558 №476278 
Две проблемы, я снес debian-root из дев и не могу теперь зайти в рут из оболочки. Можно это исправить?

И можно ли без потери данных увеличить раздел var?
Аноним 10/05/15 Вск 16:31:35 #559 №476321 
14312646953300.jpg
Есть база данных пикрилейтед. Есть код:
$db = mysql_connect('сервер', 'логин','пароль');
mysql_select_db("база" ,$db);
$sql = mysql_query("SELECT `des` FROM `Index` WHERE `id` > 0" ,$db);
$res = mysql_fetch_row ($sql);
print_r($res);


По идее, код должен вывести массив со всеми значениями des. Но на практике, выводит
Array ( [0] => One )
Почему так происходит?
Аноним 10/05/15 Вск 17:12:14 #560 №476338 
>>476321
>>476335
Аноним 10/05/15 Вск 20:28:45 #561 №476441 
>>476278

> И можно ли без потери данных увеличить раздел var?
Речь о реальном диске или образе виртуальной машины? Вообще, некоторые fs позволяют менять их размер: http://www.o-nix.com/pages/reshenija-v-linux/resize-ext2ext3ext4.php

Заметь что там делается все в 2 этапа: сначала переразбивается диск, выделяя больше места для одного из разделов, затем файловая система на этом разделе растягивается чтобы занять дополнительное место. Обрати внимание, что fdisk довольно низкоуровневая вещь и она легко выполнит даже опасные операции. Там расширяют раздел за счет идущей за ним неразмеченной области. Если ты хочешь расширить раздел за счет идущего за ним другого раздела то подход из статьи не поможет, ты просто затрешь начало файловой системы следующего раздела. В этом случае надо переместить или сжать следующий раздел, высвободив место для расширения, а потом только расширять предыдущий.

Прежде чем делать такие вещи, убедись что понимаешь как именно разбит диск и какие разделы в каком порядке идут. Я не знаю, как сейчас с GPT партициями, но раньше например там была какая-то хитрая схема (MBR разделы), что у тебя может быть только 3 основных раздела, а все остальные были внутри четвертого расширенного:

http://help.ubuntu.ru/manual/%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%82%D0%BA%D0%B0_%D0%B4%D0%B8%D1%81%D0%BA%D0%B0
https://ru.wikipedia.org/wiki/%D0%A0%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB_%D0%B4%D0%B8%D1%81%D0%BA%D0%B0#.D0.92.D0.B8.D0.B4.D1.8B_.D1.80.D0.B0.D0.B7.D0.B4.D0.B5.D0.BB.D0.BE.D0.B2

Соответвенно если ты хочешь расширить раздел внутри расширенного за счет первичного то все становится сложнее.

С другой стороны если у тебя GPT разделы то написанные выше не актуально: https://ru.wikipedia.org/wiki/%D0%A2%D0%B0%D0%B1%D0%BB%D0%B8%D1%86%D0%B0_%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D0%BE%D0%B2_GUID

Потому если есть возможность то я бы забекапил данные, если они важны. Высока вероятность все сломать. В /var из важного, как я понимаю, базы данных MySQL?

> я снес debian-root из дев и не могу теперь зайти в рут из оболочки.
Я не очень понял, ты удалил устройство /dev/sdXXX соответствующее диску из папки /dev? Не понимаю, зачем ты это сделал, но этой папкой управляет отдельный демон и при перезагрузке он наверно пропишет туда нужные устройства заново.
Аноним 10/05/15 Вск 20:33:01 #562 №476445 
>>476278

И еще, я не уверен что вообще стоит создавать кучу разделов. По моему, проще использовать один раздел для всего (или, если у тебя несколько операционных систем, то делаешь небольшой раздел для линукса, небольшой системный раздел для windows, а все данные хранишь на отдельном разделе который доступен и из линукса и из windows).

>>476321

> По идее, код должен вывести массив со всеми значениями des.
Нет. не должен. Открой мануал: http://php.net/manual/ru/function.mysql-fetch-row.php

там написано как именно работает эта функция. Она читает только одну строчку из массива результатов.

Алсо имей в виду, расширение mysql давно уже устарело и ты учишься по каким-то древним 10-летней давности учебникам.
Аноним 10/05/15 Вск 20:40:40 #563 №476453 
>>476255

Не знаю, наверно стоит сделать как будет быстрее.

>>476265

Я еще вот такое нашел: https://merchant.webmoney.ru/conf/guide.asp#8 — там какое-то оповещение предусмотрено.

Вот тут https://merchant.webmoney.ru/conf/guide.asp#2 написано что ты можешь указать обработчик на своем сайте который будет получать информацию о платеже.

Ты хотя бы документацию-то прочел? Прочти.



Аноним 10/05/15 Вск 20:49:27 #564 №476460 
>>476445
>там написано как именно работает эта функция. Она читает только одну строчку из массива результатов.
А есть какая-нибудь функция, которая дала бы весь результат, а не только первую строку без циклов?
Аноним 10/05/15 Вск 22:17:03 #565 №476539 
пиздетц ниче не панятна((9
основы я давно знаю а дальше ваще хуй знают че наверное мотивации мало сейчас у меня н
Аноним 10/05/15 Вск 22:18:29 #566 №476540 
>>476539
хуёво браток((
Аноним 10/05/15 Вск 22:19:16 #567 №476541 
Учу сейчас модель mvc. Кое-что заинтересовало.
Вот получаем мы uri - /controller/action. И контроллер, и действие статичны, мы их описали.
А почему тогда, например, на хабре сделано так:
/post/137664 ?
То есть экшен динамический. Почему не /post?id=137664, например?
Ладно, если бы все так было сделано, мы бы просто изменили правило разбора экшена на этапе роутинга. Но ведь есть страницы /auth/login и /auth/register, где экшен уже статичен.
Смысл в таком подходе?
Аноним 10/05/15 Вск 23:25:33 #568 №476580 
>>476541
Не особо понятен твой вопрос.
> Почему не /post?id=137664, например?
Потому что это не красиво визуально и со стороны сео через get массив не рекомендуется передавать ничего. Да и вобще переменные в get это костыль.
Аноним 10/05/15 Вск 23:49:20 #569 №476584 
>>476580
Ютуб же делает вот так:
/watch?v=OK0L1MhMlYY

А вообще я понял, в чем дело. Похоже, у хабра нет точки входа, а просто директории, как на сосаче.
Я говорил про подход, когда мы делаем сначала переадресацию к index.php, разбираем uri и вызываем нужный контроллер.
Аноним 11/05/15 Пнд 00:31:58 #570 №476599 
>>476539
>>476540
очень хуево((9

может кто сталкивался с таким???
Аноним 11/05/15 Пнд 00:49:29 #571 №476603 
>>476541

> . Почему не /post?id=137664, например?
раньше говорили что поисковики хуже ценят такие страницы так как они думают что все адреса вроде /post это одна страница, просто с разными параметрами отображения. Хотя я не уверен что это сейчас так, я не сеошник, и например Hacker News использует такие адреса и прекрасно ищется гуглом: https://news.ycombinator.com/item?id=9521151

Ну и не очень красивые адреса. Все таки в идеологии HTTP путь (это то что идет после домена в URL) обозначает какой-то ресурс (файл или страницу) на сервере, а параметры после знака вопроса это дополнительные опции, например для сортировки, поиска или еще чего-нибудь. Ну то есть /post/123456 хорошо описывает ресурс «пост № 123456».

Потому адрес /post/123456 с точки зрения концепции HTTP лучше чем /post?id=123456

Вот мой урок с мыслями про то какие стоит делать URL: https://gist.github.com/codedokode/772a4ccc03e41d6b7cba

> Вот получаем мы uri - /controller/action. И контроллер, и действие статичны, мы их описали.
MVC это идея разделения кода на 3 части (котроллер, модель, представление). Она ничего не говорит про то как выглядит URL, это решаешь ты. Соответственно никто не говорит о том что там всегда в начале должен идти контроллер. URL может выглядеть как угодно, но лучше конечно делать их красивыми и читабельными и соответствующими концепциям HTTP.

В твоем случае никто не запрещает приписать параметры после action:

/posts/read/12345678
/posts/read?id=1234 (не так красиво и не очень соответствует идее HTTP)

Или вообще сделать словесный URL:

/new-intel-netbooks (только старайся не делать длинные URL, это вредит читабельности)

> Ладно, если бы все так было сделано, мы бы просто изменили правило разбора экшена на этапе роутинга. Но ведь есть страницы /auth/login и /auth/register, где экшен уже статичен.
Ты можешь настроить роутинг как угодно, ты не обязан придерживаться тут единого стиля.

>>476580

> Да и вобще переменные в get это костыль.
Не всегда. Это дополнительные параметры, которые идеально подходят для сортировки или поиска. Почему сортировку лучше делать через параметры? Потому что с точки зрения HTTP ресурс у нас один — список объявлений, а поиск и сортировка это просто разные представления этого ресурса:

/ads?sortBy=date&search=cars

>>476584

Я видел на Ютубе и /watch/123456 для встраивания в страницу и короткий домен youtu.be. Вообще, что касается ютуба это просто исторически так сделано и они не хотят менять чтобы не ломать ссылки. Да и зачем менять если все работает.

Аноним 11/05/15 Пнд 00:53:37 #572 №476604 
>>476584

> Похоже, у хабра нет точки входа, а просто директории, как на сосаче.
Ты это никак не можешь определить не имея исходников. Сервер можно настроить как угодно, можно настроить что он по URL /1.jpg будет отдавать файл 2.jpg например.

Точно также URL /posts/some-post.html не значит что там на самом деле HTML страница. Ты никак это не можешь определить снаружи (на самом деле ты можешь конечно попробовать догадаться по заголовкам, но не без 100% гарантии).
Аноним 11/05/15 Пнд 01:07:18 #573 №476615 
>>476603
Понятно, все сложнее, чем я думал.

А какой тебе профит учить нубов?
Аноним 11/05/15 Пнд 01:19:50 #574 №476623 
>>476615

Интересно же. Раньше я просто двачевал капчу вообще без всякой пользы. И кстати как косвенный эффект, я лучше знаю всякие фреймворки и библиотеки, с которыми не работал но которые заставляю изучать анонов.
Аноним 11/05/15 Пнд 19:50:22 #575 №476982 
Посоны, в чем может быть проблема? В общем есть форма с текстовыми полями и она отлично работает через AJAX. Но практически такая же форма ни в какую не хочет загружать прикрепленные файлы и отправлять их обработчику. Целый день уже мучаюсь и не могу найти решение данной проблемы.

Вроде бы есть рабочий код тут http://positron-it.ru/stati/otpravlenie_soobwenij_s_vlozheniem_po_ajax/ , но у меня на локалхосте он не хочет работать почему-то. Это в нем проблема?
Аноним 11/05/15 Пнд 20:10:41 #576 №476999 
>>476623
Опчик, ты такой няша, просто не передать словами ^_^
А ты сам работаешь где-то?
Аноним 11/05/15 Пнд 20:51:49 #577 №477019 
Довольно легко дались задачки 1-гоуровня, а на первой 2-го сразу сел в лужу. Это задача "Пиши верно", а именно в ней не могу понять, как сделать функции, меняющую первую букву предложения заглавной. Пока идея такая - выдернуть с помощью mb_substr первую букву в предложении, а потом mb_strtoupper перевести ее в верхний регистр. Сделать все это в цикле пройдя через все предложения. Загвоздка в том, что там еще не удалены пробелы и первую букву надо будет отсчитывать непонятно как. Или там надо применять регулярки?
Аноним 11/05/15 Пнд 20:56:08 #578 №477023 
>>477019
ucfirst
Аноним 11/05/15 Пнд 20:57:37 #579 №477024 
>>477023
ucfirst вроде не работает с многобайтовыми кодировками, поэтому на странице этой функции в мануале, в комментариях люди пишут свои велосипеды. Еслиб все было так просто, этой задачи бы не было в учебнике.
Аноним 11/05/15 Пнд 21:04:17 #580 №477028 
>>477019
Разбиваешь строку на предложения, с ними делаешь то, ты описал, затем склеиваешь обратно.
http://php.net/manual/ru/function.explode.php
Аноним 11/05/15 Пнд 21:16:32 #581 №477046 
>>477028
>>477023
Второе предложение массива: " не смотрел еще black mesa". Получается пробел в начале заменится на (заглавный?) пробел.
Аноним 11/05/15 Пнд 21:26:18 #582 №477054 
>>477046
trim
ltrim
rtrim
Аноним 12/05/15 Втр 00:30:29 #583 №477130 
Читал всякие статейки и нашёл http://spyvak.name/page/sobesedovanie .

Там ведь неправильно решена задача про переворачивание строки? Ведь если оперативной памяти под скрипт 70мб, а строка, которую нужно перевернуть весит 100мб, то она уже не помещается и её нужно как-то считывать по частям откуда-то и переворачивать или нет?
Аноним 12/05/15 Втр 00:32:01 #584 №477132 
>>476982

Открой инспектор (Ctrl + Shift + I) в браузере на вкладке Network и попробуй отправить форму. Посмотри что передается.

На стороне PHP поставь var_dump($_FILES, $_POST) чтобы увидеть что приходит.

Алсо почитай теорию https://php.net/manual/ru/tutorial.forms.php

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

>>476999

Фрилансю и работаю удаленно.

>>477019

> Пока идея такая - выдернуть с помощью mb_substr первую букву в предложении, а потом mb_strtoupper перевести ее в верхний регистр.
Правильная идея.

> Загвоздка в том, что там еще не удалены пробелы и первую букву надо будет отсчитывать непонятно как.
функция trim отрежет пробелы с краев.

>>477023

Нет, она не работает, почитай урок https://gist.github.com/codedokode/ff99e357e9860ea169b8

>>477046

> Получается пробел в начале заменится на (заглавный?) пробел.
Пробел так и останется пробелом. заменяются только символы для которых есть заглавный аналогичный символ. Цифры и знаки, а также символы языков где нет регистра букв, не меняются.


Аноним 12/05/15 Втр 01:08:29 #585 №477142 
>>477130

> ? Ведь если оперативной памяти под скрипт 70мб, а строка, которую нужно перевернуть весит 100мб, то она уже не помещается и её нужно как-то считывать по частям откуда-то и переворачивать или нет?

Пример конечно неудачный так как трудно найти сервер с 70 мб памяти. Но в реальности часто встречаются ситуации когда надо работать с большими объемами данных, например собранные на большом андронном коллайдере данные весят терабайты, так же огромные объемы данных выдают устройства анализа ДНК (например в биологии).

Ну или более простой пример: дампы карт разных стран открытого проекта OpenStreetMap весят гигабайты в сжатом виде.

В таких случаях мы должны как-то обрабатывать файл по частям. Например прочитать первые N Мб, обработать, записать на диск, прочитать вторые N Мб, и так далее.

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

Классический пример такой задачи — это дисковая сортировка файла, который не вмещается в оперативную память. Такой файл разбивается на блоки, блоки сортируются и сохраняются во временный файл. После чего мы читаем эти блоки построчно и объядиняем: https://ru.wikipedia.org/wiki/%D0%A1%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%BB%D0%B8%D1%8F%D0%BD%D0%B8%D0%B5%D0%BC

Есть также обобщенный подход для реализации алгоритмов по принципу «разделяй и властвуй», он называется map-reduce. Он требует от тебя написать алгоритм в виде 2 функций, map и reduce и предполагает такой порядок работы:

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

Преимущество такого подхода в том что имея функции map/reduce мы можем запускать их как в последовательном режиме, так и параллельно, например на нескольких ядрах или нескольких машинах, не меняя сам алгоритм. Более того, мы можем масштабировать систему на ходу, добавляя новые машины по мере необходимости.

map-reduce вроде бы используется в Гугл для обработки больших объеимов данных:

https://ru.wikipedia.org/wiki/MapReduce
http://habrahabr.ru/post/103467/

А теперь вернемся к предложенному мной алгоритму:

> читать исходный файл с конца блоками, переворачивать блок и дописывать в выходной файл

правильный ли он? Если у нас однобайтная кодировка и буква занимает 1 байт то да. Если у нас utf-8 или другая многобайтная кодировка то нет, этот алгоритм сломает все буквы так как буква состояшая из нескольких байт:

D0 D8

будет записана в первернутом виде

D8 D0

И разумеется файл станет нечитаемым. Что делать? Более того, если мы берем блок из файла, то нет гарантии что он будет обрезан по границам символов. мы можем в начале получить «хвост» буквы из предыдущего блока и в конце начало буквы, заканчивающейся в следующем блоке.

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

(хвост буквы из пред. блока) (буква 1) (буква 2) ... ( буква N) (начало последней буквы)

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

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

Для начала можешь прочесть про суму кодировку utf-8: https://ru.wikipedia.org/wiki/UTF-8

Заметь что там надо хотя бы немного понимать двоичную и шестнадцатеричную систему счисления.

Посмотреть код букв можно так:

http://ideone.com/q74IN8

> 48 65 6c 6c 6f
Это латинница

> 20
Пробел

> d0 bf d1 80 d0 b8 d0 b2 d0 b5 d1 82
Русские буквы, в utf-8 каждая кодируется ровно 2 байтами, пример как ты видишь код первого и второго байта находятся в разных диапазонах (первый d0-d1, второй 80-bf) и натренировавшись можно их различать.
Аноним 12/05/15 Втр 01:40:01 #586 №477150 
http://pastebin.com/HkJQbHcG
Посредством fpdf, пытаюсь собрать pdf из нескольких выбранных файлов(multiple). Все изображения заливаются в корень с index.php. Но fpdf упорно ругается что не может их открыть. Что я делаю не так?


Warning: getimagesize(08kNmVUXGAJM.jpg) [function.getimagesize]: failed to open stream: No such file or directory in A:\home\test1.ru\www\m\fpdf.php on line 1213
FPDF error: Missing or incorrect image file: 08kNmVUXGAJM.jpg
Аноним 12/05/15 Втр 01:45:33 #587 №477152 
>>477150

Ты не указал полный путь к картинке значит она ищется только в текущем каталоге. Увидеть текущий каталог можно через echo getcwd(), поменять через chdir.


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


Аноним 12/05/15 Втр 07:27:07 #588 №477186 
>>477019
Вот, сделал:
http://ideone.com/Jiufhp
Не очень понял как добавить ? и ! в explode/ b еще у тебя в примере довольно большая функция fixText, а у меня совсем короткая получилась.
Алсо, уже можно перекатываться на какое-нибудь IDE, а то ideone не очень удобен (частенько хочется отменить действие например).
Аноним 12/05/15 Втр 09:54:13 #589 №477208 
slim таки кто-то использует? Чем лучше silex?
Аноним 12/05/15 Втр 10:11:22 #590 №477212 
Тред уже в бамплимите. Не пора ли пилить перекат?
Аноним 12/05/15 Втр 10:23:46 #591 №477215 
>>477212

Скоро сделаем. Еще даже 600 постов нет, а раньше мы до 650/700/750 сидели.
Аноним 12/05/15 Втр 10:50:41 #592 №477225 
ОП, что думаешь про Symfony?
Аноним 12/05/15 Втр 12:32:33 #593 №477239 
>>477186
>http://ideone.com/Jiufhp
Ой, что-то сделал следующую задачу и понял, что первую сделал криво.
Проверь пока вторую, первую я скоро переделаю:
http://ideone.com/K84ggh
Аноним 12/05/15 Втр 15:33:04 #594 №477298 
Этот тред вообще жив еще?
http://ideone.com/K1tkxJ
Почему дампает NULL?
Аноним 12/05/15 Втр 18:44:35 #595 №477393 
На некоторых сайтах количество страниц меняется в зависимости от базы данных. Типа если 20 товаров и по пять на страницу, то будет четыре страницы вида www.domen.ru/catalog/4, а если сорок товаров, то будет ещё и www.domen.ru/catalog/8. Откуда берутся эти дополнительные страницы? Как они генерируются? И как ставится нумеровка снизу, указывающая на количество доступных страниц и текущую страницу?
Аноним 12/05/15 Втр 18:55:29 #596 №477401 
Пиздец, юкоз параша требует денег, чтобы пхп скрипты работали?
Аноним 12/05/15 Втр 19:02:21 #597 №477403 
>>477393
http://php-zametki.ru/php-prodvinutym/104-extends-pagination.html
Аноним 12/05/15 Втр 21:15:09 #598 №477502 
>>477401

Нахуй тебе юкоз?
Аноним 12/05/15 Втр 21:16:10 #599 №477503 
>>477502
Нужен хостинг, чтобы проверить одну штуку. На локалке это нереально реализовать.
Аноним 12/05/15 Втр 21:17:36 #600 №477504 
>>477503

Попробуй хостингер, вроде неплохой вариант. Год назад пользовался, вполне себе на уровне для бесплатного хостинга.
Аноним 12/05/15 Втр 21:22:43 #601 №477507 
>>477504
Вот сейчас зарегистрировался на myfreehosting.ru, залил пару файлов на фтп, но они не открываются, выдает 404. То-ли я что не так делаю, то-ли сервис мозги ебёт. Причем для редактирования файлы открываются, а по прямой ссылке типа sitename.myfreehosting.ru/test.html нет.
Аноним 12/05/15 Втр 21:27:19 #602 №477510 
>>477507

Ну там же оно не сразу доступным становится, нужно время для делегирования домена.
Аноним 12/05/15 Втр 22:40:52 #603 №477538 
Не могу понять логики подобных подзапросов:
http://phpclub.ru/mysql/doc/example-maximum-column-group-row.html
Код вроде элементарный, а какой тут должен быть ход мыслей, чтобы решить задание, не улавливаю.
Что здесь возвращает подзапрос (массив значений?), каким макаром он ссылается на алиас из внешнего запроса?
В общем, если кто сможет объяснить на пальцах, в какой последовательности сервер обрабатывает подобную инструкцию, буду благодарен.

SELECT article, dealer, price
FROM shop s1
WHERE price=(SELECT MAX(s2.price)
FROM shop s2
WHERE s1.article = s2.article);
Аноним 12/05/15 Втр 22:41:34 #604 №477539 
>>477507
НА ХОСТИНГЕРЕ ИДИОТ БЛЯТЬ.
А ЭТУ ХУЙНЮ ВЫКИНЬ.
Аноним 12/05/15 Втр 23:05:49 #605 №477551 
Хочу написать что-то интересное для себя. Либо борду, либо доску объявлений.
Есть ли смысл сначала писать без фреймворков, а потом портировать? В целях самообучения.
Аноним 13/05/15 Срд 00:47:19 #606 №477602 
>>477186

> Не очень понял как добавить ? и ! в explode
explode не умеет разбивать строку по нескольким символам сразу. Для этого нужна более мощная функция preg_split, которая принимает регулярное выражение. Она находит в строке все места, соответствующие выражению, вырезает их и возвращает массив оставшихся (не соответствующих выражению) кусочков.

Мануал http://php.net/manual/ru/function.preg-split.php

> еще у тебя в примере довольно большая функция fixText, а у меня совсем короткая получилась.
Ну хорошо, если короткая.

> уже можно перекатываться на какое-нибудь IDE, а то ideone не очень удобен
Да, конечно. Выбери какой-нибудь редактор или IDE и пользуйся ими. Ты также можешь установить себе PHP чтобы запускать программы без ideone (а в том же PhpStorm их вообще можно прямо в IDE запускать одной кнопкой).

Вот урок по установке PHP https://gist.github.com/codedokode/7054af4a03865c4cc863

> http://ideone.com/Jiufhp

> не понял, почему надо писать &перед переменной, взял из мануала
Это плохо, что не понял. По умолчанию в PHP переменные в функцию передаются по значению, то есть передается не сама переменная, а копия ее значения. Если функция меняет эту копию, то сама исходная переменная не меняется. Знак & говорит что надо передавать не копию, а саму исходную переменную по ссылке, так, что ее можно изменить внутри функции.

Если ты не поставишь & то ты меняешь только копию переменной внутри функции, а сам элемент массива останется неизменным.

Вот тут описана передача по ссылке: http://php.net/manual/ru/functions.arguments.php#functions.arguments.by-reference

Мануал про ссылки: http://php.net/manual/ru/language.references.php

Я не советую копировать код если ты не понял, как он работает. Чтобы убедиться, что ты все понял, давай переделаем array_walk на array_map (она к тому же не требует использования ссылок).

В остальном все хорошо, программа работает верно.
Аноним 13/05/15 Срд 01:00:41 #607 №477618 
Задача про лайки. Взорвала мой мозг.
Пришлось довольствоваться утешительным призом
>давай начнем с более простой задачи: просто выведи 5 самых популярных пользователей.
Хорошо, хоть это получилоьс.
https://gist.github.com/anonymous/72887bb131a8fb88a657

Реквестирую подсказку полного решения этой задачи.
Нехило я психанул сегодня. >>477538
Это тоже мои потуги.

Пойду попробую поспать.
Я тут заметил, что недосыпание негативно влияет на усмтвенные способности.
Аноним 13/05/15 Срд 01:02:39 #608 №477620 
>>477208

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

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

>>477225

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

>>477239

> $arr[$i] = $newParts; //составляем новый массив из предложений
Можно писать просто $arr[] = ... это автоматически проставит подходящий числовой индекс для элемента.

> foreach ($parts as &$value)
Зачем тут & ? Не пиши то, что не понимаешь сам. Ты должен каждый символ в коде понимать.

> krsort($words); //сортируем массив из слов по значениям в обратном порядке
Для переворачивания больше подходит специально для этого придуманная функция array_reverse.

> foreach ($parts as &$value) {
Вторую переменную логично назвать $part. value ничего не значит и только сбиваетс толку. А еще лучше использовать тут слова foreach ($sentences as $sentence) ...

> array_walk(
Давай на array_map попробуем заменить? Чтобы без ссылок обойтись.

> добавляем точку в конце (коряво?)
Сойдет

> //все буквы в нижний регистр
Это называется комментарий Капитана Очевидность. В комментариях стоит писать не что делает функция (это любой может прочесть в мануале), а зачем и почему ты это делаешь, например «после переворачивания строки последнее слово будет с заглавной буквы. Исправим это, переведя все буквы в нижний регистр». Видишь, в чем разница? Я объясняю для какой цели тут использована эта функция и почему ее нельзя убрать.

Такие комментарии стоит ставить в не очень очевидных местах.

Соответственно комментарий вроде «//объединяем слова в предложения» особого смысла не несет, так как это просто описание функции implode.

Аноним 13/05/15 Срд 01:03:50 #609 №477621 
>>477298

> $parts = trim($parts);
Ты передаешь в функцию trim массив вместо строки, о чем она возмущенно пишет ниже:

> PHP Warning: trim() expects parameter 1 to be string, array given in /home/2WwBpt/prog.php on line 24

Так как она не может обработать массив, то возвращает null в знак протеста.

Аноним 13/05/15 Срд 01:08:02 #610 №477622 
>>477393

Адрес в URL не обязан соответствовать папкам и файлам на сервере. Если в адресе написано /catalog/8 это на значит что на сервере есть папка с таким именем. Ты можешь настроить правила обработки URL как угодно (какой скрипт вызывать или какой файл отдавать при обращении по такому-то URL).

Вот мой урок про виды URL: https://gist.github.com/codedokode/772a4ccc03e41d6b7cba

> Откуда берутся эти дополнительные страницы? Как они генерируются?
Там все обращения по адресам вроде /catalog/XXX перенаправлены на один и тот же скрипт, например catalog.php. Он анализирует какая цифра указана в URL и соответственно при выборке из базы добавляет конструкцию LIMIT которая говорит пропустить первые N строк.

> И как ставится нумеровка снизу, указывающая на количество доступных страниц и текущую страницу?
Циклом for может быть?

Если будешь делать нашу задачу про список студентов (в первом посте) то там тоже надо сделать постраничную навигацию.
Аноним 13/05/15 Срд 01:21:46 #611 №477625 
>>477401

Есть бесплатные PHP хостинги, причем западные даже без рекламы.

Юкоз я бы вообще никому не советовал. Там куча рекламы и ограничений и он расчитан на создание сайтов через их конструктор, а не программированием.

>>477507

Посмотри логи на сервере (если они есть в панели управления), посмотри что пишет инспектор в браузере (Ctrl + sHift + I) на вкладке Network. Из твоего описания вообще ничего не ясно.

>>477538

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

> Что здесь возвращает подзапрос (массив значений?), каким макаром он ссылается на алиас из внешнего запроса?

Здесь подзапрос использован внутри WHERE. Это значит что MySQL выбирает по очереди строки из таблицы shop s1 и каждую строку проверяет на соответсвие условию WHERE. Так как там подзапрос то это значит что для каждой строки по очереди выполняется отдельный запрос с подстановкой туда конкретного значения, например, если у нас в таблице такие значения:

s1.article
----------
10
20
30

То для первой строчки будет выполнен подзапрос

SELECT MAX(s2.price) FROM shop s2 WHERE 10 = s2.article

Для второй

SELECT MAX(s2.price) FROM shop s2 WHERE 20 = s2.article

И так далее.

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

Так как подзапрос использован в равенстве

WHERE x = (...)

То он должен вернуть ровно 1 значение, иначе будет ошибка. Подзапросы можно использовать в таких местах:

— сравнения или выражения (подзапрос должен вернуть одно значение):

WHERE x = (...)
WHERE x > (...)

— IN (подзапрос может вернуть много строк с 1 колонкой)

WHERE x IN (select ...)

— FROM/JOIN (подзапрос может вернуть много строк и колонок)

SELECT ... FROM (SELECT ...) ...

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

Мануал:

http://www.mysql.ru/docs/gruber/mg10.html
http://www.mysql.ru/docs/gruber/mg11.html

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

Аноним 13/05/15 Срд 01:25:18 #612 №477627 
>>477551

По моему, ты либо потратишь время зря (то есть быстрее сразу писать на фрйемворке), либо бросишь и так и не перенесешь. Но ты можешь попробовать, если хочешь. Я готов прокомментировать код и дать советы. Но только тогда надо писать с использованием ООП и MVC, быдлокод на функциях и массивах в стиле PHP4 сейчас никому не нужен.

Также, я бы советовал сначала решить одну-две задачи из верхнего поста (про студентов и файлообменник), они дадут тебе полезные знания. Если ты учился по плохим устаревшим учебникам или видеокурсам то они помогут тебе переучиться на современнный нормальный стиль программирования. Хотя бы комментарии к задаче про студентов почитай.

Аноним 13/05/15 Срд 01:38:11 #613 №477628 
>>477618

> Задача про лайки. Взорвала мой мозг.
Не беда, я могу дать подсказки. Там достаточно 2 джойнов + группировка по моему в самом оптимальном варианте. Но если ты можешь сделать еще проще, то я не против.

Код лучше постить на sqlfiddle так как там он выполняется и можно увидеть результат.

Советы и замечания:

> name VARCHAR(50)
Для обязательных к заполнению полей принято ставить NOT NULL. NULL значит «неизвестно, не указано», а ведь у нас вряд ли разрешены пользователи без имени.

Между таблицами надо проставить связи через внешние ключи: http://denis.in.ua/foreign-keys-in-mysql.htm

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

who/whom плохо различаются и легко сделать опечатку, лучше писать from/to или from_user/to_user или from_id/to_id.

> PRIMARY KEY (who, whom)
Это ты правильно сделал, это защищает от повторной вставки записи с теми же значениями

По поводу подсказки:

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

При этом ты можешь наткнуться на проблему, что при джойне 2 таблиц у тебя получаются большие числа (так как одно и то же id учитывается несколько раз). Допустим юзер 1 поставил лайки 3 и 5 и получил от 4, 5, 6. Получается такая картина:

юзер кому_поставил от_кого_получил
юзер1 3 4
юзер1 3 5
юзер1 3 6
юзер1 5 4
юзер1 5 5
юзер1 5 6

То есть джойн дает нам все возможные комбинации id с учетом условий ON/WHERE (это называется полное декартовое произведение).

На таком массиве данных COUNT покажет число 6 для обоих колонок (полученных/отданных лайков), и это не то, что нам надо.

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

http://www.mysql.ru/docs/gruber/mg06.html
http://phpclub.ru/mysql/doc/group-by-functions.html

В общем, я бы хотел чтобы эта задача научила тебя мыслить именно джойнами: мы джойним таблицы, добавляем условия для отсеивания записей, группируем и получаем нужные нам данные. джойны очень важная штука и используются повсеместно.
Аноним 13/05/15 Срд 02:15:33 #614 №477638 
>>477627
Конечно я буду использовать ООП и MVC. Все твои статьи уже прочитал, довольно полезны.
Дело в том, что я уже кодил раньше, но на плюсах и питоне. Синтаксис и библиотеку самого пхп практически не знаю, планирую выучить по ходу дела. Мне главное понять архитектуру сайта и бд, как все устроено. Больше сейчас читаю про паттерны, а не сам язык.
Я посмотрел, как работает перловская wakaba. Фактически буду переписывать ее на пхп по всем правилам ООП и MVC.
Уже, кстати, появился вопрос.
Очевидно, при запросе страницы треда (/thread/214723.html) мы не будем генерировать ее каждый раз. Только при добавлении или удалении поста. В остальных случаях просто будем отдавать уже готовую.
1) Что будет, если во время отдачи страницы одному пользователю, другой - добавит пост в тред и перегенерирует ее? То есть кэширует ли пхп или апач страницы во время отдачи автоматически или это надо делать явно?
2) Допустим, нам надо отдать статичный файл (ту же страницу или картинку). Можно ли делать это на этапе роутинга, не прибегая к контроллеру? В идеале можно даже не использовать RewriteCond %{REQUEST_FILENAME} !-f в .htaccess. Запрашивать напрямую. Вопрос в том, соответствует ли это паттерну MVC?
3) Где лучше делать экранирование данных: в моделе или контроллере?
Аноним 13/05/15 Срд 03:20:01 #615 №477642 
>>477638

> Очевидно, при запросе страницы треда (/thread/214723.html) мы не будем генерировать ее каждый раз. Только при добавлении или удалении поста. В остальных случаях просто будем отдавать уже готовую.
Это довольно спорное решение и имеет как минимум такие недостатки:

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

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

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

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

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

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

> Что будет, если во время отдачи страницы одному пользователю, другой - добавит пост в тред и перегенерирует ее? То есть кэширует ли пхп или апач страницы во время отдачи автоматически или это надо делать явно?
Вот, ты правильно мыслишь. По умолчанию в линуксе файлы никак не блокируются и если один пользователь запросит страницу в то время как другой пишет в нее, то первый получит оборванный файл.

Апач тут не при чем, он не кеширует если явно не попросить, php тем более (так как он не участвует в отдаче файла).

Решения проблемы с параллельным доступом как миниум две:

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

Чтение:

linux: man flock, man fcntl

http://linux.die.net/man/2/fcntl
http://linux.die.net/man/2/flock
http://linux.die.net/man/3/fcntl

windows: msdn createfile https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx (обрати внимание на флаг dwShareMode)

> Допустим, нам надо отдать статичный файл (ту же страницу или картинку). Можно ли делать это на этапе роутинга, не прибегая к контроллеру?
Зачем доводить это до этапа роутинга? Это надо делать на уровне nginx/Апача не запуская PHP

> В идеале можно даже не использовать RewriteCond %{REQUEST_FILENAME} !-f в .htaccess.
А в чем проблема с этим условием? И я сомневаюсь что ты сможешь «запрашивать напрямую» при использовании mod_rewrite, по моему ты не очень понял как он работает.

> . Вопрос в том, соответствует ли это паттерну MVC?
паттерн MVC определяет разделение кода, который генерирует динамические страницы. Про статические он ничего не говорит, так что можно так делать.

> Где лучше делать экранирование данных: в моделе или контроллере?
Там где они используются, чтобы с первого взгляда было видно что все безопасно. Соответственно экранирование HTML спецсимволов надо делать в шаблоне (либо использовать шаблоизатор с автоэкранированием), а экранирование данных для БД в той функции где выполняется запрос, причем не стоит делать это руками, используй плейсхолдеры.

Вот мои уроки по XSS и XSRF:

https://github.com/codedokode/pasta/blob/master/security/xss.md
https://github.com/codedokode/pasta/blob/master/security/xsrf.md

Ну и насчет «изучить PHP в процессе», я бы советовал все же найти время и порешать задачки с моего учебника. Они научат тебя самым часто используемым функциям, да и с опытом программирования ты их сможешь быстро решить. А то в сети можно найти кучу неправильных и устаревших примеров.

И да, почитай еще сайт phptherightway, он как раз борется с устаревшими подходами.


ОП 13/05/15 Срд 03:28:03 #616 №477643 
Аноны, кто изучает яваскрипт, почитайте хорошую статью на русском про отладчик в браузере (там про Хром, но в ФФ/IE все аналогично): http://learn.javascript.ru/debugging-chrome

Аноним 13/05/15 Срд 04:25:15 #617 №477646 
>>477642
>— нельзя сделать страницу кастомизированной для пользователя, например подсвечивать его посты и скрывать те, что не нравятся, нельзя выводить время в стиле «5 минут назад»
Почему не JS?

>— когда постов много, приходится пересоздавать огромный файл
Так в любом случае его генерировать. Только сравни: 500 человек сидят в ридонли и только открывают странички, и 10 - в это время постят. Так мы генерируем страницу не 500 раз в секунду, а 10.

>— это более сложное решение чем просто брать посты из базы и выводить. Зачем делать сложнее если можно делать проще?
Чем же? Мне кажется, даже проще. Например, получаем запрос GET /pr/res/468317.html - сразу отдаем nginx'ом.
В функциях добавления и удаления поста пишем в конце что-то типа rebuild_cache($thread_id).
Насколько я тебя понял, все упирается в нагрузку файловой системы. Можно тогда хранить снапшот треда в памяти и так же его обновлять при постинге.

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

Спасибо за ссылки, гляну.
Вообще, не ценишь ты свое время, бро. Такой пост - это же где-то час писанины.
Аноним 13/05/15 Срд 04:39:22 #618 №477649 
>>477646

> Почему не JS?
Потому что это костыли. Ведь если бы мы не усложняли себе жизнь и делали динамическую генерацию, то все бы работало само собой.

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

> Так в любом случае его генерировать. Только сравни: 500 человек сидят в ридонли и только открывают странички, и 10 - в это время постят. Так мы генерируем страницу не 500 раз в секунду, а 10.
В одном случае мы создаем только сетевой трафик + нагрузку на CPU, а в другом нагрузку на запись на диски. И неизвестно какого ресурса у тебя больше, CPU или дискового трафика. Это надо делать измерения и тесты, а не пытаться угадать (что ты явно пытаешься сделать и это неправильно).

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

> , я вспомнил, что в основном люди используют автоподгрузку, а не полное обновление страницы. Так и нагрузка на сервер выходит намного меньше.
В случае с вакабой автоподгрузка сводится к запросу всей страницы и отдачей либо 304 либо 200. Если добавлен один комментарий в тред из 500 постов мы скачиваем 501 пост.

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

> это же где-то час писанины.
Шутишь? Час на такой пост? Максимум минут 15-20, я же опытный. Алсо, я стараюсь отвечать на посты когда ем что-нибудь, чтобы зря время не терять.
Аноним 13/05/15 Срд 04:41:09 #619 №477650 
>>477646

Вообще, лучше всего было бы если бы ты набросал простой скрипт (для статической/динамической генерации страниц) и попробовал померять: дисковый трафик, сетевой, число запросов в секунду и тд.
Аноним 13/05/15 Срд 05:03:00 #620 №477653 
>>477649
>В случае с вакабой автоподгрузка сводится к запросу всей страницы и отдачей либо 304 либо 200. Если добавлен один комментарий в тред из 500 постов мы скачиваем 501 пост.
Лол, и правда. Это же крайне тупо. Мы же можем послать номер поста, на котором остановились, и получить только разницу. Подводные камни - если были удалены какие-то посты.

>>477650
Я не знаю реальную статистику, сколько людей загружает полную страницу, а сколько автообновляет. От этой пропорции все и зависит.
Аноним 13/05/15 Срд 05:12:54 #621 №477655 
>>477653

> Это же крайне тупо
Это потому что автоподгрузка изначально была в каком-то расширении к браузеру (некий «куклоскрипт» или «вишмастер» может быть?), и ее авторы не имели возможности поменять что-то на сервере.

> Я не знаю реальную статистику, сколько людей загружает полную страницу, а сколько автообновляет.
Можно взять статистику с потолка. Ну или рассмотреть 2 экстремальных сценария: только загрузка полной страницы (человек просто тыкает во все треды подряд?) или 1 загрузка + 100 обновлений + 20 отправок сообщения аяксом (активный участник треда).

Для начала ты можешь просто на бумаге прикинуть, сколько и каких операций будет выполнено в каком случае. И соответственно будет видно, что мы меняем на что.
Аноним 13/05/15 Срд 05:15:30 #622 №477656 
>>477653

> Подводные камни - если были удалены какие-то посты.
Это тоже реально реализовать:

— ведя на сервере что-то вроде журнала событий и присылая записи этого «журнала» на клиент.
— помечая удаленный пост флагом deleted = 1 вместо удаления и ставя дату обновления. При наличии поля «дата обновления» мы можем также присылать на клиент информацию об удаленных или отредактированных постах начиная с момента времени t.
Аноним 13/05/15 Срд 05:20:28 #623 №477657 
>>477653

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

Заходим на первую страницу, видим посты A, B, C, (на второй в это время D, E, F)
Аноны постят в D, E, F выталкивая их вверх
Заходим на вторую страницу раздела и снова видим A, B, C!!!

На реддите если ты посмотришь кнопку следующая/предыдущая страница, используется более хитрый подход, там не передается номер страницы. Ну и вот еще пост в тему: http://use-the-index-luke.com/no-offset (я не согласен что надо всегда отказываться от LIMIT. Нужно смотреть по ситуации).

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

Аноним 13/05/15 Срд 06:23:18 #624 №477659 
Файлообменник, еще не доделан
https://github.com/AzerusEncole/File_Sharing

Дамп
http://rghost.ru/7TSk8M57j
Аноним 13/05/15 Срд 07:56:56 #625 №477671 
Калькулятор. https://ideone.com/AUYZgZ

Чтобы добавить вычисления для чисел с плавающей точкой, надо регулярку делать или можно как-то is_float обойтись?
Аноним 13/05/15 Срд 15:32:24 #626 №477775 
>>477625
Ага, кажется начинаю догонять. Исправьте, если где-то неправильно понял.
Я догадываюсь, что WHERE работает наподобие цикла (наверняка оно там внутри так и реализовано), то есть выполнение этого запроса происходит в следующем порядке:

0. Допустим, таблица выглядит следующим образом:
article-----dealer----price
0001------A----------3.45
0001------B----------3.99
0002------A----------10.99
0003------B----------1.45
0003------C----------1.69
0003------D----------1.25

1. Сначала интерпретатор отмечает себе только что выбрать и откуда:
SELECT article, dealer, price
FROM shop s1;

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

2. Теперь, заметив предикат/клаузулу WHERE (кстати, в чем конкретно разница между п. и к.?), интерпретатор заставит сервер пройтись в цикле по всем записям, попавшим в массив/объект (или в какой там форме возвращает данные mysql).
В каждой итерации будет участвовать одна запись целиком (т.е. не только один столбец, WHERE s1.price = ... не означает, что будет взята только цена; все указанные в п.1 поля текущей записи так сказать под рукой в текущей итерации).
В первую итерацию попадет запись
0001-----A-----3.45
Я знаю что в бд все хранится в "куче", но предполагаю, что записи будут перебираться в том порядке, в каком они заносились. Впрочем, порядок неважен в данном случае.

3. Итак, на первой итерации результирующий запрос будет выглядеть след.образом:
SELECT article, dealer, price
FROM shop s1
WHERE 3.45 = stmt;


, где stmt - это подзапрос, возвращающий одно значение.
Значит, сначала выполнится подзапрос, которому между прочим будут доступны поля текущей записи
s1.article = 0001
s1.dealer = A
s1.price = 3.45

SELECT max(s2.price)
FROM shop s2
WHERE s2.article = 0001;

Этот подзапрос выберет все записи для товара 0001 и найдет максимальное значение поля price для него.
Теперь это значение (равное 3.99, см. п.0) подставится уже в наружный запрос, и мы получим
SELECT article, dealer, price
FROM shop s1
WHERE 3.45 = 3.99;


3.45 != 3.99, значит в результирующий набор эта запись (0001 - A - 3.45) не попадет.

4. На последующих итерациях будут повторяться действия, описанные в п.3, но в качестве текущего объекта будут браться значения уже из второй, третьей и т.д. записи.
Например, на второй итерации получим следующие операции:
s1.article = 0001
s1.dealer = B
s1.price = 3.99

SELECT article, dealer, price
FROM shop s1
WHERE 3.99 = ( SELECT max(s2.price)
FROM shop s2
WHERE s2.article = 0001 );


, что сведется к следующему:
SELECT article, dealer, price
FROM shop s1
WHERE 3.99 =3.99;


(3.99 === 3.99) ? добавляем в результирующий набор : пропускаем

5. Повторить пункт 3 для каждой записи таблицы shop.

Итого:
1) Подзапросы действительно не очень удобны для чтения и понимания.
Мне вот пришлось написать такое полотно с анализом, чтобы понять что собственно тут происходит.
Возможно, опытные программисты уже на автомате пишут такие запросы, не задумываясь.
А пока приходится напрягаться, чтобы понять логику кода.
2) Неоптимизированный код. Для каждой записи выполняется подзапрос, насколько я понял.
Это все равно что написать в php
for ($i = 0; $i < count($array); $i ++){}


ОК, вечером попробую написать этот же запрос джойнами, попытаюсь наконец решить задачу про лайки. >>477628
Аноним 13/05/15 Срд 15:43:43 #627 №477778 
>>477775
В связи с вышесказанным, возникает подозрение, что у меня и большинства людей, испытывающих сложности с программированием, проблема заключается именно в слабом понимании алгоритмов.
Иногда может мешать еще слабо развитая фантазия и память (сложно представить себе последовательность действий, плюс удержать это все в оперативной памяти головы). Но это решается при помощи ручки и листа бумаги, куда можно записывать промежуточные вычисления.

Не подкинете ли хороших материалов по составлению алгоритмов, анализу и решению задач?
Да, я слышал про гугл, воспользуюсь. Но форум как бы и предназначен для экономии времени, не каждый результат поиска может быть полезным.
Аноним 13/05/15 Срд 16:34:15 #628 №477799 
>>477775

Общий порядок выполнения запроса такой:

— FROM/JOIN (MySQL присматривается из какой таблички мы выбираем строчки, если есть JOIN то выбираем из нескольких сразу)
— отсеивание всех строк через WHERE в цикле (условие WHERE применяется по очереди к каждой строке и соответственно на каждом шаге цикла выполняется подзапрос)
— группировка строк через GROUP BY если он есть
— отсеивание строк через HAVING если он есть
— сортировка через ORDER BY если он есть
— отсечение через LIMIT если он есть
— выборка полей указанных после SELECT и возврат результата пользователю

Разумеется это общий план запроса. MySQL старается применять оптимизации, но они применяются только так, чтобы не влиять на результат.

> кстати, в чем конкретно разница между п. и к
Предикат это условие, CLAUSE это часть запроса, например FROM, WHERE, ORDER

> Сначала интерпретатор отмечает себе только что выбрать и откуда:
Ты ничего не путаешь? Интерпретатор PHP не выполняет SQL запросы, он просто передает запрос базе, а она возвращает результат (в своем особом формате который PHP превращает в массив или что ты его попросишь).

> интерпретатор заставит сервер пройтись в цикле по всем записям, попавшим в массив/объект
запрос целиком выполняется на стороне MySQL. PHP не делает никаких циклов, он просто передает текст запроса никак не интерпретируя его. Иначе был бы бардак, каждый должен заниматься своим делом.

> Неоптимизированный код. Для каждой записи выполняется подзапрос, насколько я понял.
База данных может делать оптимизации если она достаточно умная, а запрос дает такую возможность. Причем разные базы данных (MSSQl, Oracle, MySQL, Postgresql) обладают разным уровнем оптимизаций. Проверить это можно командой EXPLAIN которая покажет план и порядок выполнения запроса. Так наугад сказать нельзя, оптимизируется это или нет.

Аноним 13/05/15 Срд 16:53:27 #629 №477814 
>>477778

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

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

В твоем случае, могу предложить тебе переписать запрос джойнами, а также решить задачку про лайки (из задач на MySQL, ссылка в первом посте, там же кроме задач есть пара ссылок на теорию).

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

> Не подкинете ли хороших материалов по составлению алгоритмов, анализу и решению задач?
Это обширная тема. Гуглить надо по словам «алгоритмы и структуры данных».

Вот я нашел какие-то видеолекции (хотя я сам не очень люблю такой формат да и лекторы там не идеальные):

https://www.lektorium.tv/course/22823
http://habrahabr.ru/company/abbyy/blog/251561/

Есть такая книга но она очень старая, не уверен, стоит ли на нее время тратить: http://snilit.tspu.ru/uploads/files/default/virt.pdf

Есть такая интересная книга, может быть ее стоит почитать: http://aliev.me/runestone/ — она использует Питон для примеров, но это не принципиально, ты можешь те же алгоритмы на любом языке реализовать.

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

Но вообще я не думаю, что тебе это так уж нужно.
Аноним 13/05/15 Срд 17:38:42 #630 №477840 
Чего у мня не работает sqlfiddle?
Говорит
"Oops! Something went wrong.
Try it again..."
Хром версия 41.0.2272.76 Ubuntu 14.04

update
под виндовс то же самое
Ну и ладно.
Аноним 13/05/15 Срд 17:51:46 #631 №477845 
>>477840

Бывает, попробуй чуть попозже зайти. У меня сейчас работает: http://sqlfiddle.com/#!9/348ce/1

Или ты что-то не то ввел туда, может какой-нибудь вечный запрос?
Аноним 13/05/15 Срд 20:57:00 #632 №477953 
>>477845
Да, уже работает, иногда тормозит почему-то.

>>477628
Там был подвох в дистинкте.
Плюс я плохо представлял, как происходит джойн и группировка.
Сегодня просидел полдня, почитал мануалы. Потом разобрал этот запрос поэтапно, то есть сначала с одним джойном и без группировки.
Затем добавил второй джойн, и убрав группировку стало ясно, что проблему вызывают повторяющиеся строки.
Их убрал дистинктом.
http://sqlfiddle.com/#!9/c6cea/32

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

А, черт, там же еще нужно вывести взаимные лайки.
Ладно, мне же больше нечем этой ночью заняться.
Аноним 13/05/15 Срд 21:16:59 #633 №477962 
>>477602
>Чтобы убедиться, что ты все понял, давай переделаем array_walk на array_map (она к тому же не требует использования ссылок).
Я понял, спасибо тебе за хорошее объяснение.
1-я задача, исправленная:
http://ideone.com/UwUKmc
>>477620
2-я задача, исправленная (убрал лишние комментарии и все что ты написал сделал):
http://ideone.com/V9kcYW
Аноним 13/05/15 Срд 21:18:02 #634 №477963 
>>477655
>>477656
>>477657
>Ну и сложная вещь тут не обновления треда. Гораздо сложнее обновлять страницы со списком тредов, так как если ты хочешь сделать их на файлах, то тебе надо при каждом постинге обновлять все HTML-файлы и это уже гораздо более тяжелая операция.
Да, ты прав. Тогда приходит на ум следующее.
Используем что-то типа memcached. И при постинге не ребилдим кэш треда, а только изменяем его иннер стейт. И страницу генерируем только при непосредственном запросе.
Получается система:
1) Юзер запрашивает полную страницу треда.
2) Смотрим, изменен ли он с последнего кэширования.
3) Если да, ребилдим и отдаем юзеру. Если нет, отдаем прямо из памяти.
Похоже, идеальный вариант.
Со списком тредов нужно работать отдельно. Чтобы не было повторений на следующих страницах, придется хранить порядок тредов на момент запроса страницы для каждого юзера.
А вообще, что-то мне подсказывает, здесь без хардкорного JS не обойтись. Как вконтакте, только сложнее, т.к. при нажатии "Обновить треды" придется их мозайкой перекладывать и добавлять новые, а не просто подгружать посты в текущей структуре.
Аноним 14/05/15 Чтв 10:42:40 #635 №478133 
Тред на нулевой не легитимный? Опчик никуда не уходит?
Аноним 14/05/15 Чтв 13:49:07 #636 №478169 
>>477963

> Используем что-то типа memcached
Я не понимаю, при чем тут мемкеш. В memcache не надо будет перестраивать данные? проблема была в том, что в архитектуре вакабы надо обновлять большое число файлов при каждом постинге, и от того что ты их перенесешь в кеш, ситуация не поменяется. Ты просто предлагаешь наугад всякие бессмысленные идеи никак их не обосновывая.

Ты даже не посчитал например какой объем памяти потребуется.

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

Кстати нгинкс умеет отдавать страницы напрямую из мемкеша.

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

Вообще, делай как хочешь. Мне кажется, мы сейчас делаем другую ошибку — слишком много обсуждаем и слишком мало делаем.
Аноним 14/05/15 Чтв 13:51:18 #637 №478170 
>>478133

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

Надо сначала только тут все непроверенный задачки проверить.
Аноним 14/05/15 Чтв 14:02:10 #638 №478172 
Господин ОП позволил мне кидать тред особенно уродливые куски кода, дабы он мог пояснить что я делаю не так. За что я ему очень благодарен.
Начну с простого http://pastebin.com/2mDjEcgP
Аноним 14/05/15 Чтв 14:08:54 #639 №478173 
>>478172

> что я делаю не так
Смешиваешь в одном файле HTML-код и работу с базой. Получается нечитаемая каша. Надо разносить это в разные файлы как описано тут http://www.phpinfo.su/articles/practice/shablony_v_php.html

Используешь <?. Он может быть отключен где-то и потому надо исплоьзовать толкьо <?php и <?=

Вместо <? echo надо писать <?=

Функции mysql_ давно устарели. Ты мануал открывал? Там большими буквами это написано. Переходи на PDO.

Аноним 14/05/15 Чтв 14:09:22 #640 №478174 
>>478172
А что именно не так? Код выдает ошибку какую-то? Алсо
>mysql_query
Этим давно уже не пользуются, я хоть и не ОП, но он всегда советует изучать PDO, вот http://habrahabr.ru/post/137664/
Аноним 14/05/15 Чтв 14:10:06 #641 №478176 
>>478172

Алсо если в каком-то учебнике описывают функции mysql_ то это значит что он тоже устарел и лучше всего взять что-то поновее. Ничему хорошему там тебя не научат.
Аноним 14/05/15 Чтв 14:11:00 #642 №478177 
>>478172
>>478174
да он работает, хочу красивее писать.
Спасибо за статью, прочту.
Аноним 14/05/15 Чтв 14:22:49 #643 №478185 
Что-то у меня люто лагает sql-fiddle. Вчера иногда не запускался только скрипт, сегодня даже build schema подвисает.

Задачу про лайки таки осилил.
Выкладываю пока сырье гистом.
https://gist.github.com/anonymous/02c00de98f837d07c34c
Аноним 14/05/15 Чтв 14:33:43 #644 №478191 
>>478185

Вместо COUNT(IF) который полагается на обработку NULL лучше использовать SUM который складывает нолики и единицы.

Более так как операция сравнения = возвращает 0 или 1, мы можем даже обойтись без IF (но лучше не надо, так как с IF код гораздо понятнее и читабельнее).

А так, все верно решено. Не хочешь еще задачку про календарь или расписание решить попробовать?
Аноним 14/05/15 Чтв 15:26:38 #645 №478210 
14316063984640.png
14316063984651.png
Почему если вставлять в таблицу данные через phpMyAdmin, то они нормально отображаются, а если через php скрипт с POST параметрами, то иероглифами?
Аноним 14/05/15 Чтв 15:39:00 #646 №478212 
>>478210
В html поставил meta charset="utf8"?

После того как установишь соединение с базой, установи кодировку соединения:
mysqli_query("SET NAMES UTF8");
В PDO это делается при создании объекта:
$link = new PDO("mysql:host=localhost;dbname=DB;charset=UTF8");

Правильно настрой сервер mysql:
в my.ini в секции [mysqld] прописать

skip-character-set-client-handshake
character-set-server = utf8
init-connect='SET NAMES utf8'
collation-server=utf8_general_ci

Также желательно установить кодировку для клиента и mysqldump. Для этого в секциях [client] и [mysqldump] необходимо добавить строчку:
default-character-set=utf8

И не используй ублюдочный phpmyadmin, работай через командную строку или workbench на худой конец.
Аноним 14/05/15 Чтв 15:44:29 #647 №478214 
>>478212
Я хер знает если честно, где тут my.ini, я ведь не на локалхосте работаю, а на говнохостинге. Тут с мускулем можно только через myAdmin работать, я бы и рад по другому.
Аноним 14/05/15 Чтв 16:18:29 #648 №478224 
>>477628
>Между таблицами надо проставить внешние ключи
А это разве не ключ:
from_user INT UNSIGNED NOT NULL REFERENCES user (id)
Или там есть нюансы типа индексации или ограничений (constraints)?
Правильнее ли будет писать так:
FOREIGN KEY(from_user) REFERENCES user (id) ?
Индекс и ограничитель на внешний ключ вешается автоматически (в первом и втором варианте)? Или надо дописывать руками?

>>478191
Беспредельно желаю.
Уже смотрел на задание про базу кинотеатра. Пока мысленно набросал структуру, проверь насколько правильно продумано.

Из сущностей (таблиц, объектов):
1) Фильм Film. Имеет свойства/поля:
- id
- name
- duration enum(60, 90, 120, 150, 180)
Возможно, стоит добавить дополнительную колонку для коэффициента ценовой категории. Но для упрощения будем считать, что цена рассчитывается только в зависимости от времени начала сеанса.
2) Билет ticket:
- id
- seance_id references seance(id)
3) Seance:
- id
- datetime
- film_id references film(id)
4) Самая интересная таблица, в которой указывается цена на сеанс в зависимости от типа временного отрезка (комбинация дня и времени H:i:s). Не знаю даже, как назвать эту таблицу.
- DayOfWeek enum(1,2,3,4,5,6,7)
- TimeOfDay tinyint references timeOfDay(id)
- price float
Первичный ключ - комбинация всех трех полей.
5) Приходится вынести таблицу времен суток в отдельную сущность:
- id tinyint
- period varchar(100) -- например "утренний (9:00-11:00)"
Аноним 14/05/15 Чтв 17:08:52 #649 №478252 
>>478214
>на хостинге можно только через phpmyadmin
Не только. Спокойно можно подключаться через консоль, например:
mysql -u username -p mypasswordis1234qwerty -h mysite.ru

Ну неважно. Просто в phpmyadmin ты не понимаешь, что происходит, тыкаешь на кнопки, и "оно само" работает. Только вот не всегда так как ты хочешь.

Кодировка для баз на бесплатном хостинге скорее всего latin1 (шведская, устанавливается по умолчанию).
Соответственно и таблицы, которые ты создаешь, тыкая на кнопки, получаются в latin1.
Можно выбрать таблицу слева в дереве базы, потом кликнуть на панель sql (третья сверху, после "обзор" и "структура").
В появившемся поле вбить
alter table mytable character set utf8 collate utf8_general_ci;
и нажать ОК.
И так для каждой таблицы.

Но лучше было бы создать нормальную базу на локальном сервере, потом сделать дамп (можно через тот же phpmyadmin: панель "экспорт" вверху), и залить ее на хостинг через панель импорт.

Ну или каждый раз при соединении писать set names utf8. Кому как больше нравится.
Аноним 14/05/15 Чтв 17:29:24 #650 №478263 
>>478224

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

> duration enum(60, 90, 120, 150, 180)
Не уверен что тут надо делать ENUM. ENUM должен быть строкой, а с числами там есть баги:

http://www.mysql.ru/docs/man/ENUM.html
> Если вы вставляете число в столбец ENUM, это число воспринимается как индекс, и в таблицу записывается соответствующее этому индексу значение перечисления. (Однако, это не будет работать с LOAD DATA, который воспринимает все входящие данные как строки.) Не рекомендуется сохранять числа в перечислении, т.к. это может привести к излишней путаннице.

Более того так как ENUM это строка, ты не можешь использовать ее в математических вычислениях.

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

Аноним 14/05/15 Чтв 17:34:30 #651 №478266 
14316140704390.jpg
Приветствую php-господ ИТТ!

Сразу предупрежу что не хочу разводить холивар, но все же какую IDE ты используешь, анон? Есть дикое желание перекатиться из Sublime Text, ну или не совсем перекатиться, в сторону чего-то более мощного, функционального. Что посоветуешь? Интересуют кроссплатформенные решения, но главное под Windows и Linux, хотя если что-то действительно годное, хватит и под Linux.

Спасибо, пожалуйста.
Аноним 14/05/15 Чтв 17:36:29 #652 №478268 
>>478266

— PhpStorm (вроде есть возможность официально использовать бесплатно какую-то тестовую версию)
— Вроде еще Netbeans PHP и Zend Studio были, но я ими не пользовался
— Алсо есть еще Eclipse PDT, она совсем бесплатная но не очень навороченная
Аноним 14/05/15 Чтв 17:42:30 #653 №478271 
14316145507600.jpg
>>478268
> PhpStorm
Вроде как 30 дней триалка, лицензия стоит $199

> Netbeans PHP и Zend Studio
Попробую посмотреть, но что касается Zend, думаю он тоже стоит как самолет.

> Eclipse PDT
Сегодня установил, пикрелэйтэд. Есть баги, тормоза, не очень радует.
ОП 14/05/15 Чтв 18:02:59 #654 №478291 
>>478271

> Есть баги,
какие интересно? Уверен что это баг а не ошибка в настройке или непонимание, как оно работает? Тогда наверно стоит о нем в багтрекер написать чтобы его исправили.

> тормоза
Ты не в виртуалке запускаешь? Памяти достаточно?

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

Аноним 14/05/15 Чтв 18:06:54 #655 №478295 
>>478291
> Уверен что это баг а не ошибка в настройке
Может и не баги, может с иксами проблема, но ui иногда распидорашивает.

> Тормоза там бывают если куча плагинов включена
Я имею ввиду некоторые узкие места, например фильтры, файловый менеджер.
ОП 14/05/15 Чтв 18:09:26 #656 №478296 
>>478295

Файловый менеджер это панель с файлами слева? По моему от нее пользы нет, если у тебя в проекте больше 10 файлов то удобнее открывать их через быстрое открытие по имени, а не тыкаться в эту крошечную область экрана и искать там файлы вложенный в 5 папок.
Аноним 14/05/15 Чтв 20:08:47 #657 №478392 
14316233275980.png
>>478252
Все сделал вроде, все равно не работает. Теперь вообще любой текст содержащий русские символы не видно в таблице, просто пустые ячейки. Хотя вручную нормально вставляется а пхп скриптом нихуя. Не пойму почему.
Аноним 14/05/15 Чтв 20:19:27 #658 №478402 
>>478392
В блокноте кодировку смени с анси на ютф.
заебал
Аноним 14/05/15 Чтв 20:29:48 #659 №478409 
>>478252

> Спокойно можно подключаться через консоль, например: mysql -u username -p mypasswordis1234qwerty -h mysite.ru

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

> в секции [mysqld] прописать
> init-connect='SET NAMES utf8'

Ты уверен что это правильно? Почему ты запрос пишешь в секции для сервера, а не для клиента? И зачем делать SET NAMES если там есть какая-то опция вроде character_set_client или как-то так.

>>478392

1) PHP-скрипт сохранен в кодировке utf-8?
2) чем работаешь с базой в скрипте? PDO? mysqli? Ты так и не написал
3) при соединении с базой через PDO ты указал charset=utf8 (без минуса)?
4) в HTML-коде c формой (если открыть в браузере через Ctrl + U) стоит meta charset utf-8 или отдается кодировка в заголовке Content-Type?

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

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

http://fstrange.ru/coder/mysql/kodirovka-krakozyably.html
http://gahcep.github.io/blog/2013/01/05/mysql-utf8/
http://phpfaq.ru/charset
Аноним 14/05/15 Чтв 21:11:55 #660 №478437 
>>478409
Все, я понял в чем была проблема. Вроде бы менеджер файлов, через который я загружал файл на фтп сохранял его не в той кодировке. Сейчас залил через Filezilla и все работает.
Аноним 14/05/15 Чтв 21:25:52 #661 №478453 
>>478437
А хотя нет, все равно баг остался. Если я в bindValue буду передавать просто строку на русском языке, то она в таблице отображается. А вот если туда передавать POST переменные со строкой на русском, то ничего не вставиться.
Аноним 14/05/15 Чтв 21:34:57 #662 №478460 
>>478453
Вставь в код строчку
var_dump($_POST)
Что выведет?
Аноним 14/05/15 Чтв 21:44:00 #663 №478465 
>>478453

Ты не ответил на этот вопрос:

> 4) в HTML-коде c формой (если открыть в браузере через Ctrl + U) стоит meta charset utf-8 или отдается кодировка в заголовке Content-Type?
Аноним 14/05/15 Чтв 21:48:33 #664 №478469 
14316293139150.png
>>478460
У меня POST данные от стороннего сайта принимаются, я могу их посмотреть только уже в базе данных, сам скрипт ничего не выводит. Я для этого и запилил хостинг, потому-что на локалку не получится принять данные.
>>478465
Да, как раз собирался об этом написать. Форма передает данные на сайт вебмерчант, а тот в свою очередь присылает их обратно мне на пхп скрипт. Пикрелейтед. Я так понял все дело в accept-charset=windows-1251? То есть он принимает их в такой кодировке и в такой-же передает обратно, а они должны приходить в utf-8?
Аноним 14/05/15 Чтв 21:53:23 #665 №478473 
Всё, вот теперь точно разобрался. Нужо было перекодировать POST параметры в UTF8 Отдельно. Как я и сказал >>478469 они присылались в Windows-1251. Извиняюсь за дебильные вопросы, в кодировках я совсем нуб.
Аноним 14/05/15 Чтв 22:22:07 #666 №478497 
14316313273040.png
14316313273071.png
Первая часть задачи про бд кинотеатра.
https://gist.github.com/anonymous/8d25f5ed7fa65a77a853

В рот ебал sqlfiddle. Теперь 5.6 возвращает empty set, а 5.5 говорит Error writing file './db_2_e59db/film.frm' (Errcode: 28)
Ничего не знаю, у меня на локалке 5.5 и все работает.
Пруфы пикрелейтед.
Аноним 14/05/15 Чтв 22:31:30 #667 №478504 
14316318908820.jpg
>>478497
А, я забыл скопипастить инсерт второй таблицы...
С 11 утра сижу, щас стены кодить начну.

http://sqlfiddle.com/#!9/7107f3/1
Аноним 14/05/15 Чтв 22:45:09 #668 №478511 
14316327092150.png
14316327092171.png
Нет, я все-таки спрошу у этого мистера sqlfiddle, почему это он выдает ошибку в версии mysql 5.5, если у меня на машине тоже 5.5, а все работает?
И кто его просил менять формт даты с 2015-05-15 на May 15, 2015?
Мы здесь таких не любим.
Аноним 14/05/15 Чтв 22:55:06 #669 №478515 
>>478497

Если sqlfiddle не работает, то ладно, не надо с ним мучаться тогда. Но я не думаю, что с ним какие-то проблемы. Проблемы в твоем коде.

> Теперь 5.6 возвращает empty set,
Ну так запрос может неверный?

Вот я вставил твои команды и все заработало. Уже второй раз у меня все работает, а у тебя нет. Может тебя какой-то плохой сервер обслуживает?

Таблицы обычно называют во множественном числе, tickets, films.

> duration TINYINT UNSIGNED
Не экономь байты и ставь минимум SMALLINT, а то вдруг найдется фильм длиннее 4 часов (у TINYINT максимум 255)

Алсо, для таких не очень очевидных колонок стоит добавлять комментарий про то, что в них хранится, со словом COMMENT, который сохранится в базе и поможет другим разработчикам разобраться в твоей таблице: http://stackoverflow.com/a/22444161

Для длительности, думаю, не стоит задавать значение по умолчанию так как не очень понятно почему там именно 120.

> price FLOAT NOT NULL,
Для денег есть специальный тип DECIMAL который в отличие от флоат гарантирует сохранность всех знаков после запятой. Тут конечно можно найти обсуждение где большинство высказывется за INT: https://toster.ru/q/23947 — по моему там автор вопроса не очень адекватен. Если есть специальный тип для таких целей, глупо городить костыли с интами и домножением.

На SO высказываются за DECIMAL:

http://stackoverflow.com/questions/628637/best-data-type-for-currency-values
http://stackoverflow.com/a/22444161

Более того упоминается какие-то Generally Accepted Accounting Principles которые это рекомендуют.

> FOREIGN KEY (film_id) REFERENCES film(id),
тут стоило бы дописывать ON DELETE/ON UPDATE хотя бы чтобы попрактиковаться. ты должен подумать и выбрать подходящее действие для этих случаев.

> WHERE s2.date BETWEEN s1.date + 1 AND s1.date + INTERVAL (f1.duration) MINUTE;
Это ведь не обнаружит ситуацию когда 2 фильма начинаются в одно и то же время? А надо обнаруживать.

Вот пример: http://sqlfiddle.com/#!9/c8606/1 — не обнаруживает пересечение

Если мы сдвинем время хотя бы на 1 секунду, то обнаруживает: http://sqlfiddle.com/#!9/0db2e/1

Если ты хочешь защититься от джойна фильма самого на себя или от вывода пары по 2 раза то можно поставить условие что первый id должен быть больше второго.
Аноним 14/05/15 Чтв 23:03:03 #670 №478522 
>>478511

Я подозреваю c 5.5 там какой-то баг. 5.6 все работает — я проверил только что.

> И кто его просил менять формт даты с 2015-05-15 на May 15, 2015?
Дата это дата, а не строка.

Я думал, что ее можно временно поменять сделав SET something = 'something' но я не нашел, что надо туда вписать, можешь сам посмотреть настройки в этом списке:

https://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html

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

Также ты можешь использовать в запросе функции превращающие дату в строку как тебе удобно (но лучше не делать, мне кажется, дата и так вполне читабельна): http://stackoverflow.com/a/4596536

ОП 14/05/15 Чтв 23:13:55 #671 №478530 
Аноны чьи задачки я не проверил и анон с файлообменником, я помню о вас, проверю чуть попозже.

И анон который сделал https://github.com/Si0n/register3 я тоже помню.

И еще, аноны, что будем делать с новым тредом? Сделаем новый или перейдем в >>475689 ? С одной стороны там неправильная шапка, много неприятных невоспитанных недружелюбных троллей и нет напоминания про оформление кода (самый важный пост в треде!), с другой стороны готовый тред уже есть и картинок много.
Аноним 14/05/15 Чтв 23:14:30 #672 №478531 
>>478515
>Таблицы называют во множ.числе
Я привык, что потом это название переносится на класс объекта в php. В yii так принято, например.
>DECIMAL вместо FLOAT
Я где-то читал, что это абслоютно одно и то же, все эти типы вместе с даблом какбы оставили только для совместимости, мол раньше между ними была разница в спообе хранения данных, сейчас нет.
Но может быть я неправильно понял, или автор был не совсем компетентен.
Ага, вспомнил. Никитин из "Специалиста" это сказал. Курсы правда 2011 года, может что-то и поменялось.
27:42 https://www.youtube.com/watch?v=mENlTJ4UoD4

Ладно, я слегка удручен, пойду посплю.
Аноним 14/05/15 Чтв 23:32:16 #673 №478541 
>>478531

Разница есть.

DOUBLE это числа с плавающей точкой, по моему там 15 значащих цифр из числа сохраняется и вычисления приближенные.

NUMERIC это точный формат, хранит и вычиcляет числа с указанной точностью.

Вот мануал на англ:

https://dev.mysql.com/doc/refman/5.6/en/precision-math.html

> Precise calculations: For exact-value numbers, calculations do not introduce floating-point errors. Instead, exact precision is used. For example, MySQL treats a number such as .0001 as an exact value rather than as an approximation, and summing it 10,000 times produces a result of exactly 1, not a value that is merely “close” to 1

Для сравнения DOUBLE: https://dev.mysql.com/doc/refman/5.5/en/floating-point-types.html

> Because floating-point values are approximate and not stored as exact values, attempts to treat them as exact in comparisons may lead to problems. They are also subject to platform or implementation dependencies. For more information see Section B.5.5.8, “Problems with Floating-Point Values”

Вот по русски пост на тему: http://tarlyun.com/blog/2011/03/22/xranenie-ne-celyx-chisel-v-mysql/

Ты либо не так понял, либо знания лектора из Специалиста устарели.

И даже если бы в MySQL не было разницы, эта разница есть в других движках БД и потому надо знать смысл и назначение этого типа (а не только особенности реализации).
Аноним 15/05/15 Птн 01:59:09 #674 №478607 
>>478530
Лучше создать новый, а мочератора попросить удалить фейковый.
Аноним 15/05/15 Птн 09:54:03 #675 №478669 
отправка формы трет предыдущий get запрос, как сделать, чтобы отправка не обнуляла url, а приплюсовывала свои параметры к тем, что уже были?
Аноним 15/05/15 Птн 11:28:00 #676 №478688 
>>478669
Доступ к строке гет-запроса (query string) можно получить через массив SERVER, например
action="<?php echo $_SERVER['REQUEST_URI'].'&newquery=123';?>"
https://php.net/manual/ru/reserved.variables.server.php

Но ты уверен, что такое "присобачивание" параметров это правильное решение?
Скажи, что именно хочешь сделать. А лучше выложи код на гитхаб или пастбин.
Наверняка можно придумать более грамотный подход к формированию строки запроса.
Аноним 15/05/15 Птн 12:04:24 #677 №478695 
>>478688
а значение 123 как передать в action?
я делаю фильтр, присобачивание параметров определенно то, что нужно. я написал свой парсер url который отлично работает. И функцию, которая из get переменных формирует запрос к бд https://ideone.com/tw5KHg
Все работало как следует, пока мне не пришлось использовать форму, которая нагло удаляет предыдущие get переменные.
Аноним 15/05/15 Птн 12:44:46 #678 №478706 
>>478669

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

По твоему коду, в нем куча ошибок и такая уязвимсоть как SQL инъекция.

> foreach($url as $key => $val){
Непонятно зачем ты руками разбираешь URL когда PHP сделает это сам и складывает результаты в $_GET

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

https://ru.wikipedia.org/wiki/%D0%92%D0%BD%D0%B5%D0%B4%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_SQL-%D0%BA%D0%BE%D0%B4%D0%B0

http://forum.antichat.ru/threads/43966/

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

> if(is_string($val)){
Эта проверка бессмысленна так как parse_str возвращает только строки. Даже если это строка вида '123', она все равно считается строкой. Обрати внимание:

$x = '123'; // строка из 3 символов
$y = 123; // число 123

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

(если ты новичок в нашем треде, то знай что я обычно комментирую весь код который сюда постят, и по каждому примеру у меня обычно есть замечания)
Аноним 15/05/15 Птн 13:06:26 #679 №478715 
>>478706
да, над безопасностью надое еще поработать, благо то, что я пишу будет доступно только кругу лиц незаинтересованных в том, чтобы навредить(там провекрка есть).
Руками я разбираю затем, чтобы если в юрл уже есть значение переменной, к примеру
?user=4638, а я хочу изменить фильтр еще раз и тогда к запросу просто еще раз дописалось бы &user=4639, к примеру url станет вида ?user=4638&user=4639.
Поэтому в функции я пишу все переменные в массив и если у get переменной уже есть значение то оно перезаписывается( $url["$var"] = $val;).
По поводу is_string да, сам недавно исправил на is_numeric
Спасибо!
Аноним 15/05/15 Птн 13:20:48 #680 №478721 
>>478715

> Руками я разбираю затем, чтобы если в юрл уже есть значение переменной, к примеру
?user=4638, а я хочу изменить фильтр еще раз и тогда к запросу просто еще раз дописалось бы &user=4639, к примеру url станет вида ?user=4638&user=4639.

Незачем разбирать руками, все это уже разобранное лежит в GET и можно писать foreach ($_GET as $key => $value)

parse_str (если я не путаю) работает точно так же и в твоем случае второй user затрет первый. В массиве не может быть 2 элемента с одинаковым ключом. Ты пробовал сделать такой URL?

И если ты в SQL запросе напишешь WHERE user =1 AND user = 2 он ничего не найдет так как оба условия никогда одновременно не выполняются. Надо писать WHERE user IN (...)

Чтобы передать несколько id для юзера через строку запроса в URL, есть массивы: http://php.net/manual/ru/faq.html.php#faq.html.arrays

Не изобретай велосипед а пользуйся тем что уже есть.
Аноним 15/05/15 Птн 13:42:26 #681 №478728 
>>478721
да в том то и дело, что мне не нужно несколько id, а только один. поэтому и хочу, чтобы терло.
Ага, на счет гет понял, можно не разбивать на части, а просто пропарсить сам гет. спасибо
Аноним 15/05/15 Птн 13:55:25 #682 №478738 
>>478721
что именно является велосипедом?
Аноним 15/05/15 Птн 15:23:11 #683 №478778 
>>478738

PHP разбирает параметры из строки запроса и складывает их в массив _GET. Ты бы мог взять их из него, но вместо этого ты пытаешься разбирать URL самостоятельно. Это и есть велосипед.

Ну и массив _GET в самом начале мануала по PHP упомянут вообще-то.
Аноним 15/05/15 Птн 15:39:43 #684 №478786 
>>478778
а, ну правильно. да я знаю его и пользуюсь все время, просто чето тупанул.
Аноним 15/05/15 Птн 17:30:30 #685 №478832 
Оп-кун, мне нужно реализовать архиватор на php. Я выбрал json что бы хранить данные, как лучше всего это сделать?

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

Архив будет собой представлять файл в котором данные записанные в формате json, а именно массив со строками, это нормально?

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

все ок?
Аноним 15/05/15 Птн 17:40:39 #686 №478840 
>>478832
Как мне считать таким образом картинку и почему мне сказали обратить внимания на чтения бинарных файлов?
Аноним 15/05/15 Птн 17:45:49 #687 №478842 
>>478832
>>478840
У меня не хочет считывать побайтно, все равно читает как текстовы файлы, даже сfopen($s, "rb")
Аноним 15/05/15 Птн 18:55:48 #688 №478872 
>>478832

Хорошо, что ты тут спрашиваешь. У тебя пока план не идеален и я попробую описать, что именно не так.

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

> Я так понял, что лучше всего его считывать побайтно и представлять ввиде строки, правильно?
Файл это набор байтов на диске с именем. В плане скорости выгоднее читать большими кусками, например по 100 Кб так как в этом случае получается в 100 000 раз меньше вызовов функции чем если читать по 1 байту за раз и код работает гораздо быстрее.

Строка в PHP это тоже набор байтов, только в памяти. Ты можешь узнать число байт в строке с помощью strlen (обрати внимание, что именно число байт, а не символов. 1 символ не равен 1 байту), ты можешь получить N-й байт (не символ!) начиная с нулевого, с помощью $str[100] и ты можешь получить его код в виде числа от 0 до 255 с помощью ord($str[100]). Также, ты можешь преобразовать число в строку из 1 байта с помощью chr: chr(64) вернет строку "@" состояющую из 1 байта с кодом 64 (который соответствует символу @ как ты уже догадался наверно).

Также в PHP есть еще 2 функции, pack и unpack, для упаковывания чисел в последовательность байтов и обратной распаковки. Они тебе пригодятся, так что почитай про них.

Соответственно функции fread, file_get_contents делают как раз то, что тебе нужно: перемещают байты из файла на диске в строку в памяти.

> Архив будет собой представлять файл в котором данные записанные в формате json, а именно массив со строками, это нормально?
Нет. Преимущество JSON это некоторая читаемость человеком (в этой задаче она не требуется) и возможность легкой обработки яваскриптом (тут тоже не требуется). Следовательно JSON не дает тут никаких преимуществ, а только увеличивает вес получившегося файла за счет лишних символов. JSON это формат для веба, а не архивов.

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

Заметь, что большинство форматов бинарные. Это значит, что они хранят данные не как читабельный набор символов, а просто набор байт. Это позволяет максимально компактно записывать данные. Ну например 9-разрядное число требует 9 цифр (и 9 байт) для записи в текстовом виде, а в бинарном всего 4 байта.

Потому тебе придется изучить как хранить число (например, длину файла) в виде нескольких байт. Вот кое-что на эту тему:

http://www.5byte.ru/11/0008.php
http://kuzelenkov.narod.ru/mati/book/inform/inform5.html
http://habrahabr.ru/post/233245/

(статьи не очень качественные так что задавай вопросы, если что)

Если кратко, то мы записываем число в двоичном виде, затем разбиваем на группы по 8 бит (на байты) и сохраняем эти байты. Это почти самый компактный способ. Заметь, что тебе не придется делать это руками, функции pack/unpack умеют это делать.

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

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

— gzip — открытый формат сжатия. Он не поддерживает упаковку нескольких файлов, а только сжатие одного файла. В линукс, если тебе надо сжать несколько файлов, ты сначала объединяешь из в один командой tar (опять же, изучи формат tar-файла), а потом жмешь tar через gzip. Это дает более хорошее сжатие чем если сжимать по отдельности, но имеет тот недостаток что для чтения списка файлов в архиве ты должен распаковать gzip-архив целиком (прочитав целиком его с диска, что может занять время), достать из него tar-файл и прочитать список файлов в немю

Описание форматов:

https://ru.wikipedia.org/wiki/Gzip
https://tools.ietf.org/html/rfc1952 (на англ, но зато подробно)
http://www.opennet.ru/docs/RUS/tar/tar-11.html
http://cvs.savannah.gnu.org/viewvc/checkout/tar/tar/src/tar.h?content-type=text/plain

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

— zip — не открытый формат сжатия. zip-файл состоит из 2 частей: оглавления, хранящего список и информацию о файлах в архиве и тела, которое хранит сами сжатые файлы. За счет того, что zip файл содержит оглавление, ты можешь просмотреть список файлов в архиве не распаковывая его целиком, только прочитав начало файла.

Описание:

http://en.wikipedia.org/wiki/Zip_(file_format)
https://users.cs.jmu.edu/buchhofp/forensics/formats/pkzip.html
https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT

С форматами разобрались, пора поговорить про само сжатие.





Аноним 15/05/15 Птн 19:07:41 #689 №478876 
>>478872
Мне не нужно сжимать данные, мне нужно создать из них архив, извини, что не уточнил.

Я скину код, как допишу, сегодня вечером думаю, мне до понедельника надо закончить
Аноним 15/05/15 Птн 19:09:24 #690 №478878 
>>478872
И как считать картинку по байтно? у меня выходит набор не читаймых симоволов
Аноним 15/05/15 Птн 19:24:47 #691 №478891 
>>478840
>>478842

Код покажи, телепатов в треде нет.

>>478832

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

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

Сжатие тесно связано с количеством информации (энтропией). Надо искать какие-то закономерности в информации и записывать их в более компактном виде. Ну например, если в файле идет 100 раз подряд байт с кодом 46, мы можем вместо 100 одинаковых байтов записать так:

(число повторений, например 100) (повторяющийся байт, например 46)

как видишь, мы записали 2 байтами то, что занимало 100 байт. Это называется RLE:

https://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%B4%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BB%D0%B8%D0%BD_%D1%81%D0%B5%D1%80%D0%B8%D0%B9

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

https://ru.wikipedia.org/wiki/LZ77
http://habrahabr.ru/post/141827/

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

Вот LZMA, это по сути то же самое, только с более сложным (но более компактным) способом кодирования данных: https://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Markov_chain_algorithm

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

https://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0

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

http://habrahabr.ru/post/231177/
https://ru.wikipedia.org/wiki/Deflate
http://compression.ru/download/articles/lz/mihalchik_deflate_decoding.html (кстати это годный сайт про алгоритмы сжатия)

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

Вот алгоритмы оптимизированные под конкретный вид данных:

https://ru.wikipedia.org/wiki/PNG
https://www.artlebedev.ru/tools/technogrette/img/png-1/
http://netghost.narod.ru/gff2/graphics/summary/png.htm

http://compression.ru/book/part2/part2__3.htm (алгоритм JPEG использует сжатие с потерями, пытаясь отбросить детали которые глаз видит хуже всего)
http://algolist.manual.ru/compress/image/jpeg.php
https://ru.wikipedia.org/wiki/JPEG

Для кодирования последовательностей чисел (например междленно меняющихся сигналов или id документов в поисковом индексе) есть https://ru.wikipedia.org/wiki/%D0%94%D0%B5%D0%BB%D1%8C%D1%82%D0%B0-%D0%BA%D0%BE%D0%B4%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5

Для аудио есть FLAC, MP3, OGG Vorbis
Для видео ты наверно и сам слышал названия разных алгоритмов начиная с древнего MPEG и заканчивая H.264, VP9 и подобными.

Ты хоть осознаешь во что ты ввязался со своим заданием?

Аноним 15/05/15 Птн 19:25:16 #692 №478893 
>>478876

Если архив то логично использовать tar.
Аноним 15/05/15 Птн 19:26:33 #693 №478895 
>>478878

А что ты ожидаешь увидеть в бинарном файле с картинкой? какие символы?
Аноним 15/05/15 Птн 19:28:43 #694 №478897 
Мне нужно создать создать архиватор используя форматы данные json, xml (etc) или придумать свой. СЖАТИЯ ДАННЫХ НЕТ.

КАК СЧИТАТЬ ЛЮБОЙ ФАЙЛ в строку, а не только текстовый?!
Аноним 15/05/15 Птн 19:29:05 #695 №478898 
>>478895
Мне нужно, как-то его сохранить в архив, как?
Аноним 15/05/15 Птн 20:03:00 #696 №478916 
Извините, народ, я разобрался. Я затупил. Простите все.
Напишу, покажу код, скажешь ОП, что не так, хорошо?

Я потом расскажу, что и зачем надо было.
Аноним 15/05/15 Птн 20:13:12 #697 №478918 
Может кто-то подскажет почему мне советовали обратить внимания на бинарные файлы?
AzerusEncole ОП 15/05/15 Птн 20:18:51 #698 №478923 
>>477659

Советы и замечания по файлообменнику https://github.com/AzerusEncole/File_Sharing

Дамп SQL надо положить в репозиторий. Вот захочет кто-то скачать проект, как он его запустит без дампа? И структура БД это часть твоего проекта, какой смысл хранить её отдельно? Разумеется, в этом случае дамп должен содержать только структуру таблицы, без самих данных в ней.

Папки .idea, файлы внутри thumbs, uploads, vendor не должны загружаться в репозиторий. Содержимое папки vendor скачает композер, ну а файлы пользователь может закачать сам. Изучи как работает .gitignore и сделай примерно так:

— перенеси папки и файлы куда-нибудь в другое место
— закоммить проект (гит подумает что файлы удалены)
— внеси изменения в gitignore и закоммить
— верни файлы на место. теперь гит их не увидит.

Мануал по gitignore: https://git-scm.com/book/ru/v1/%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D1%8B-Git-%D0%97%D0%B0%D0%BF%D0%B8%D1%81%D1%8C-%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D0%B9-%D0%B2-%D1%80%D0%B5%D0%BF%D0%BE%D0%B7%D0%B8%D1%82%D0%BE%D1%80%D0%B8%D0%B9#Игнорирование-файлов

Насчет файла composer.json, хватило бы только require, остальные поля заполняют только если ты хочешь сделать отдельную библиотеку, ну да ладно, хуже не будет.

Ручная загрузка классов через require усложнит тебе жизнь когда файлов станет больше. Советую изучить возможности композера по автозагрузке и сделать автозагрузку классов через файл composer.json. Есть такая статья http://habrahabr.ru/post/149678/ но она старая и не описывает формат PSR-4, он описан только в официальной доке:

https://getcomposer.org/doc/01-basic-usage.md#autoloading
https://getcomposer.org/doc/04-schema.md#autoload

> ini_set('display_errors', 1);
Это наверно лучше делать в php.ini на твоем компьютере, так как непраивльно показывать ошибки на боевом сервере, их незачем видеть пользователям, они должны идти только в лог.

сами команды error_reporting, ini_set надо перенести ниже чем use, так как use принято писать первыми в файле.

> https://github.com/AzerusEncole/File_Sharing/blob/master/index.php#L23
параметры соединения с БД надо вынести в отдельный файл config.php чтобы можно было их менять не трогая сам код.

> if ($file === NULL || !$file->isValid()) {
> return $app['twig']->render('main.twig');
Надо выводить сообщение об ошибке, можно без подробностей, а не показывать молча главную страницу и ставить пользователя в тупик.

> $app->get('/download/{id}', function ($id) use ($app) {
Скачивать файлы через PHP довольно неэффективно — Апач, а тем более nginx делают это с затратой горазло меньших ресурсов и могут выдержать гораздо больше пользователей (а ведь на файлообменнике скачивание это основная функция).

Есть такие варианты:

— настроить переписывание в htaccess так, чтобы при обращении по URL /download/realname-1234/желаемое-имя.txt отдавался бы файл /upload/realname-1234 (при этом браузер пользователя берет имя файла из последнего сегмента URL)

Статья: http://habrahabr.ru/company/sprinthost/blog/129560/ + есть официальная дока на сайте Апача на английском

Подход с htaccess работает только в Апаче. Для nginx придется написать отдельное правило с регулярным выражением. Зато в скачивании никак не участвует PHP.

— использовать специальный заголовок X-SendFile. В этом случае при попытке скачивания PHP скрипт отдает вместо файла этот заголовок и завершается, а веб-сервер перхватывает его и отдает реальный файл. Такой подход позволяет PHP скрипту только инициировать скачивание и может использоваться для ограничения доступа, защиты от прямого скачивания, учета числа скачиваний, и т.д. Инфа: http://habrahabr.ru/post/151795/

Для nginx используется аналогичный подход, только заголовок называется по другому, X-Accel-Redirect. Чтобы это работало, надо установить в Апач/nginx соотв. модуль.

У нас еще есть вопрос по безопасности. Что если злоумышленник закачает на твой сервер файл evil.php с вредоносным кодом, а затем попробует его скачать по прямой ссылке через папку /uploads/123evil.php ? Скрипт выполнится? Тогда твой сервер взломан.

Второй вариант взлома: закачиваем файл .htaccess (этот файл задает настройки Апача для папки) и им меняем настройки сервера на нужные нам, разрешая запускать любые файлы как php скрипт. Этот способ взлома может сработать там, где например запрещают загружать файлы с расширением php (что недостаточно так как есть несколько способов обхода этого).

защита:

— с помощью htaccess и php_flag engine 0 отключить выполнение PHP скриптов в папке загрузки. Подвох: на некоторых хостингах эта директива отключена и ты окажешься беззащитен
— переименовывать файлы с гарантированно безопасным расширением вроде txt при сохранении

Обрати внимание, что у Апача есть опасная особенность: в некоторых конфигурациях если он видит незнакомое расширение у файла, то смотрит на предыдущее. Ну например evil.php.lalala он может воспринять как PHP файл и выполнить.

Последнее замечание по коду работы с базой. Вот это вот ужасное изобретение:

> public function execute($sql, $params) {
Во-первых глядя на функцию мы не можем увидеть откуда в нее приходит запрос и гарантировать что она безопасна. Во-вторых, ты с ее помощью размазал работу с базой по всей своей программе вместо того, чтобы сконцентрировать в одном классе. Вот как должно быть:

public function insertFile(...)
public function findAllFiles(...)
public function searchFileByName(...)

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

Также, заметь что у тебя в функции добавления файла аж 6 аргументов. Это много и легко забыть их порядок. А функция поиска файлов возвращает массив непонятно какого вида. Я предлагаю чуть усложнить код и добавить объект File представляющий информацию о файле. Мы сможем передавать этот объект для вставки и возвращать функциями выборки из базы. Это чуть увеличит объем кода, но все равно без этого более сложное приложение нормально не написать, так что лучше учиться сейчас.

Вот урок на тему работы с БД: https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md

Файлы в этой папке https://github.com/AzerusEncole/File_Sharing/tree/master/templates лучше все называть c расширением twig чтобы не было путаницы.

Если есть какие-то вопросы, задавай.

После исправления посмотрим на код еще раз.

Вот еще от робота замечания:

------------

В файле ./classes/Connection.php:

> catch (PDOException $e) {
> echo $e->getMessage();
> }

Здесь ты ловишь исключение и самостоятельно его выводишь. Это плохая идея, так как об исключении узнает пользователь сайта (и ничего не поймет), а ты не узнаешь, так как оно не пишется в логи. Не надо ловить и выводить исключения через echo, PHP сам по умолчанию ловит все непойманные исключения, записывает их в лог (который ты можешь позже прочесть) и, если включен display_errors в php.ini, выводит информацию об исключении на экран (а если выключен то выводится белая страница, что конечно не очень красиво).

Если ты хочешь выводить красивую страницу-заглушку для пользователя при возникновении исключения, удобнее всего задействовать обработчик непойманных исключений, который задается функцией set_exception_handler (мануал: http://php.net/manual/ru/function.set-exception-handler.php ). Не забудь выдавать HTTP-код вроде 500, это положено по стандарту HTTP и это подскажет поисковикам не индексировать страницу ошибки. (примечание: Силекс скорее всего содержит свой способ для создания такой страницы-заглушки и надо использовать его).

Урок про исключения: https://gist.github.com/codedokode/65d43ca5ac95c762bc1a

Задал ли ты кодировку соединения с базой при работе через PDO? Это можно сделать либо параметром charset= при соединении либо командой SET NAMES в PDO::MYSQL_ATTR_INIT_COMMAND. Мануал: http://php.net/manual/ru/ref.pdo-mysql.connection.php

Кажется, ты не используешь строгий режим в MySQL. Зря. MySQL более тщательно проверяет твои запросы и вместо предупреждений (которые ты не увидишь) выдает ошибки при попытке вставить неправильные данные. Ну к примеру, если у тебя есть колонка типа varchar(200) и ты попытаешься вставить в нее строку из 300 символов, в нестрогом режиме MySQL молча отрежет лишнее (и в базе окажется обрезанная строка), а в строгом выдаст ошибку.

Использование строгого режима экономит твое время на исправление неправильно вставленных данных. Статья на хабре: http://habrahabr.ru/post/116922/

Включить строгий режим можно сделав при соединении с БД запрос SET sql_mode='STRICT_ALL_TABLES'. В PDO это удобно сделать опцией PDO::MYSQL_ATTR_INIT_COMMAND при создании объекта PDO.

В файле ./templates/file.twig:

Слеш в конце одиночного тега (<img src="./thumbs/{{ file.id …=""/>) используется только в XHTML и XML, в HTML он не ставится.

Аноним 15/05/15 Птн 20:23:13 #699 №478925 
>>478897

Точно так же как и текстовый: командами file_get_contents, fread

>>478898

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

И что значит «сохранить в архив»? Архив это такой же файл и запись в него делается теми же командами что и любой другой файл: fil_put_contents (записать целиком), fwrite (по частям). Я думаю fwrite тут удоюнее, так как она не требует держать все файлы в памяти.

>>478918

напиши больше подробностей, кто когда и зачем. Или ты тот анон что архиватор пишет? Я советовал обратить внимание так как все архиваторы использую бинарный формат.
Аноним 15/05/15 Птн 20:29:59 #700 №478927 
>>477671

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

Чтобы в нынешнем виде добавить поддержку дробей, надо завести дополнительную переменную-флаг которая значит «в числе встретилась точка/запятая». Затем проверять этот флаг при сборке числа из цифр, если ранее встретилась запятая то прибавлять цифры к числу не умножением на 10, а по другому алгоритму. Ну например можно сделать отдельную переменную с названием «множитель для дробных цифр» и добавлять цифру к числу с ее учетом: первый раз как число десятых, второй раз как число сотых, третий как число тысячных и тд. (ну или множитель можно получить как 10 в степени «минус номер цифры», например для третьей цифры после запятой это 10 в минус третьей или одна тысячная).

В общем, надо немного усложнить код. Советую попробовать это сделать, хорошее упражнение.

> if ($op == '+') {
> if ($op == '-') {
Это лучше писать в виде блока if/elseif чтобы было видно что все варианты взаимоисключающие.

Сама программа работает верно.

Аноним 15/05/15 Птн 20:42:58 #701 №478938 
>>477962

> 1-я задача, исправленная:

> $value = trim($value);
> return($value);
тут лучше сразу писать return trim($value); А когда напишешь, остановиться на секунду и спросить себя: чем твоя функция отличается от функции trim? Если ничем то стоит ли ее создавать вообще? Не проще ли в array_map передать саму trim?

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

http://habrahabr.ru/sandbox/22836/
http://habrahabr.ru/post/134916/ (тут с картинками)

Если ты используешь php Doc то такие комментарии во-первых будут распознавать IDE (и показывать например при наведении на функцию), во-вторых из них можно автоматически генерировать документацию к проекту, вот пример такой документации:

http://www.doctrine-project.org/api/orm/2.2/class-Doctrine.ORM.EntityManager.html

А вот исходный файл с которого она сгенерирована, с комментариями:

http://www.doctrine-project.org/api/orm/2.2/source-class-Doctrine.ORM.EntityManager.html (если ты будешь хорошо учиться то потом сможешь понимать такой код)

В остальном, все верно.

> 2-я задача, исправленная

> $i = 0;
Неиспользуемая переменная. Их надо убирать, так как они сбивают с толку читающего. Это как рецепт в котором в начале написано «помойте горсть риса», при этом сам рис больше нигде не используется.

В остальном все правильно.
Аноним 15/05/15 Птн 21:11:37 #702 №478954 
>>478925
Да, я тот анон, что архиватор пишет. Больше подробностей будет в начале следующей недели, отпишусь, как и зачем, и почему истерил, лол.

Спасибо, я уже понял. Работает все. Задание учебное и надо просто сохранять архив в формате json, потому, что готовые решения запрещенны.
Аноним 15/05/15 Птн 21:35:09 #703 №478960 
Так, а что тред такой вялый? Раньше помню не успевал читать. Перекат все-таки будет или нет?
Аноним 16/05/15 Суб 00:32:48 #704 №479044 
json_encode выдает ошибку 5. у меня полюбому будут некоректный символы, когда я считываю картинку. что делать?
Аноним 16/05/15 Суб 01:12:15 #705 №479053 
На локалхосте file_get_contents работает на определенный сайт, а на хостинге нет. В чем может быть проблема?
Аноним 16/05/15 Суб 02:32:45 #706 №479065 
>>479044
Закодируй http://php.net/manual/ru/function.base64-encode.php и будет всё валидно.
Аноним 16/05/15 Суб 02:33:25 #707 №479066 
>>478960
Наступило лето, все гуляют наверное, лол.
Аноним 16/05/15 Суб 02:44:51 #708 №479069 
>>479065

Твой совет к сожалению не несет объяснения, откуда проблемы. И не предупреждает что base 64 увеличивает вес на 33%. Это уже не архиватор, а какой-то расширятор и лишнее-место-на-диске-поглощатор.

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

так что выход, да, действительно, закодировать тело файла в base64 превратив его тем самым в валидную текстовую строку из 64 видов символов. И увеличив размер на 33%.

Я не понимаю, что делает анон, но архиватром это при всем желании нельзя назвать. Почему нельзя сделать бинарную упаковку наподобие tar? Я же не написал взять программу tar, я имел в виду изучить этот формат и создавать архивы в нем. Тогда архивы будут распаковываться программами вроде 7zip и будут весить примерно как исходные файлы, а не на треть больше. Это какое-то наркоманское задание, я не знаю кто его придумал, но оно скорее учит неправильным вещам чем полезым. таких заданий быть не должно.

Аноним 16/05/15 Суб 11:22:22 #709 №479125 
ну че решили? перекат в фейкотред или создание нового?
Аноним 16/05/15 Суб 11:27:39 #710 №479126 
>>479069
По поводу 33% веса думаю надо исправить формат, иначе ничего не выйдет. Надо просто дописать две функции, которые будут кодировать строку и декодировать
Аноним 16/05/15 Суб 16:13:22 #711 №479260 
http://ideone.com/j1XLia

Оп-кун, я допилял архиватор. Я не знаю, как эта хрень работает, но архив занимает чуть меньше 3кб , а файлы сами по себе около 4.
Аноним 16/05/15 Суб 17:13:30 #712 №479308 
>>479125
все в фейкотред
Аноним 16/05/15 Суб 21:53:22 #713 №479427 
Тут остался еще кто-то живой или я один тут сижу? Официального переката не было вроде.
Аноним 16/05/15 Суб 21:58:54 #714 №479429 
>>479427

Оп весь день проспал, и только недавно проснулся, да, надо бы новый тред сделать.
Аноним 16/05/15 Суб 22:16:38 #715 №479440 
Ну и куда перекатываться?
Аноним 16/05/15 Суб 22:24:46 #716 №479446 
>>479440

Погоди, погоди, там еще у анона надо код проверить. Если у тебя вопрос какой-то то можешь пока тут его задать.
Аноним 16/05/15 Суб 22:31:38 #717 №479451 
Посоны, что делать? Доделал сайт и случайно его удалил. Ищу его с помощью всяких разных прог для восстановления файлов, но они находят что угодно, только не мой сайт.
Аноним 16/05/15 Суб 23:35:51 #718 №479500 
>>479446
Что если нам передадут, например, миллиард переменных через GET? Как php будет реагировать?
ОП 17/05/15 Вск 00:28:24 #719 №479531 
>>479500

GET переменые передаются через адресную строку, в URL. Веб-сервер (например Апач) имеет ограничение на длину URL которое задается директивой http://httpd.apache.org/docs/2.4/mod/core.html#limitrequestline и по умолчанию она равно 8190 байт то есть максимум 8190 латинских символов. Так как каждая GET переменная должна содержать хотя бы имя, знак = и знак & то получается около 2500 переменных

Если прислать более длинную строку URL то веб-сервер отвергнет запрос с какоим-то кодом 4xx, не помню точно с каким.

Заметь что это ограничение не действует на POST так как там переменные передаются в теле запроса которое может иметь размер в несколько мегабайт.

Потому в PHP есть второе ограничение, на макисмальное число GET/POST/COOKIE переменных: http://php.net/manual/ru/info.configuration.php#ini.max-input-vars — по умолчанию оно равно 1000.

Таким образом миллиард переменных не дойдет. Также, если ты исплоьзуешь GET ты должен помнить про ограничение на длину URL. Также, так как форма отправляется из браузера то браузер тоже ограничивает длину URL и по моему безопасным значением считается 2000 байт, если больше то в каких-то браузерах твоя форма не будет работать или данные будут отрезаться. Для больших объемов данных используй POST, а не GET.
Аноним 17/05/15 Вск 00:35:30 #720 №479534 
>>468317
ОП, что можешь сказать о симфони2? насколько сложно изучить? учитывая, что я его в глаза не видел, есть ли шансы за неделю изучить и выполнить тестовое задание(немного шарю в yii):

Реализовать каталог товаров на symfony2 без использования дополнительных бандлов, не идущих в стандартной поставке симфони.
1. Реализовать EAV модель. (Создать доктриновские сущности, связать их и построить на их основе структуру БД)
2. Реализовать фильтрацию по значениям характеристик товара. (построить фильтр на чекбоксах, как в интернет-магазинах) http://screencloud.net/v/4t5M
3. Фильтр должен работать как AJAXово, так и при нажатии на кнопку «Подобрать» с перезагрузкой страницы.
4. Реализуйте сортировку по цене (убывание, возрастание) с хранением пользовательского выбора в куках. При фильтрации выбранная сортировка сбиваться не должна.
5. Реализуйте фасеты для значений фильтра (как на скриншоте).
Аноним 17/05/15 Вск 01:27:55 #721 №479553 
>>479531
ОП-кун, а ты на архиватор не смотрел?
Вот, он. По хорошему стоит добавить, как я понимаю, запись через временный файл, что бы не хранить все это в памяти. А как прототип как тебе? Там еще кстати один баг, который не сохраняет папки, но я его исправлю завтра, думаю
>>479260
Аноним 17/05/15 Вск 01:28:50 #722 №479555 
>>479531
Спасибо.
Аноним 17/05/15 Вск 01:48:47 #723 №479561 
>>479534

Симфони сложный, так что это маловероятно, если ты и сделаешь задание то все равно знания будут обрывочные и недостаточные чтобы полноценно пользоваться фреймворком.
!.CzKQna1OU 17/05/15 Вск 03:41:39 #724 №479594 
test
Аноним 17/05/15 Вск 05:28:23 #725 №479604 
>>479260

> . Я не знаю, как эта хрень работает
Это плохо

> if ($handler = opendir($path)){
> while (false !== ($file = readdir($handler))){
Это старый и неудобный подход. Гораздо удобнее рекурсивно читать каталог через рекурсивный итератор файловой системы:

http://php.net/manual/ru/class.recursivedirectoryiterator.php

Итератор это объект по которому можно пройтись циклом foreach. Рекурсивный итератор это когда некоторые элементы итератора сами являются итераторами (папка содержит другие файлы).

> echo "Something went wrong in function readFolder. Sorry. \n";
Ты не пишешь причину ошибки, это плохо, првада PHP выводит ее сам в виде предупреждения, так что тут это не проблема. Но в таких случаях принято использовать исключения: https://gist.github.com/codedokode/65d43ca5ac95c762bc1a

Если у тебя есть код

if (условие) {
50 строк
} else {
2 строки
}

То его надо попробовать перевернуть, чтобы было

if (не выполняется условие) {
2 строки
} else {
50 строк
}

А еще лучше

if (не выполняется условие) {
выкинуть исключение;
}

50 строк;

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

> while ($byte = fread($inputStream, 1024*1024)){
Это неудачное решение. Во-первых, если их файла прочитается строка "0" то она будет воспринята как false и цикл завершится. Во-вторых, функция fread возвращает false при ошибке или пустую строку "" при достижении конца файла и эти ситуации надо бы различать.

Ну и наконец тут незачем городить цикл, так как файл целиком можно прочесть одной командой file_get_contents.

> $file['type'] = filetype($path);
А зачем это?

> echo "No such file or directory"."\n";
это неверное сообщение. Причина ошибки может быть в другом.

> но архив занимает чуть меньше 3кб , а файлы сами по себе около 4.
Значит там ошибка и часть данных теряется. Ты бы мог глазами посмотреть JSON и попробовать найти чего там не хватает. Должно получаться на 33% больше чем исходные файлы + немного оверхеда от самого JSON.

Аноним 17/05/15 Вск 05:28:46 #726 №479605 
Аноны, новый тред тут: >>479598
Аноним 17/05/15 Вск 10:21:51 #727 №479625 
>>479604
filetype что бы знать папка ли это или нет в массиве
comments powered by Disqus