Вы видите копию треда, сохраненную 5 декабря 2014 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
Это тред для начинающих. Не написал за свою жизнь ни одной программы? Ты наш человек.
Требуемые знания: умение читать. Устанавливать пока что ничего не требуется, разве что редактор кода вроде Sublime Text 3, Notepad++, Netbeans PHP или PhpStorm (необязательно).
Предыдущий тред был тут: >>399059
У нас есть уроки по основам PHP, они собраны и выложены по адресу http://archive-ipq-co.narod.ru Если ты ньюфаг, просто решай задачки оттуда, они там реально простые, и пости сюда ссылки на решения, мы посмотрим и скажем, правильно или нет и дадим совет, если можно что-то улучшить. Если не совсем ньюфаг, напиши, что ты знаешь, что нет, что хочешь изучить, я дам тебе какую-нибудь задачку посложнее. После прохождения учебника напиши, ОП даст тебе более сложные задания.
Есть задачки по основам JS и DOM, хорошие, многие их с ходу решить не могут, попроси, дадим ссылку. Есть задачка на MySQL.
Правила: ведем себя воспитанно, помогаем новичкам, постим ссылки на решения задачек, ОП их проверяет и дает советы и замечания.
ОП, как всегда, помогает и дает советы, отвечает на самые нубские и простые вопросы. У ОПа есть почта, так что даже если он не появляется в треде уже неделю, вы всегда можете написать ему что-то хорошее. ОП обычно занят, но где-то раз в сутки в треде появляется.
Оформляй код аккуратно!!! например пропусти через phpformatter.com . Также, если ты пользуешься IDE вроде PhpStorm, Netbeans, Eclipse, то в них эта опция встроена, подробнее: https://gist.github.com/codedokode/8759492
Что почитать?
Мануал по PHP — http://www.php.net/manual/ru/langref.php
Сайт phptherightway
По PHP: Профессиональное программирование на PHP Джордж Шлосснейгл
По PHP: Мэтт Зандстра — PHP: Объекты, шаблоны, методики программирования
JS: learn.javascript.ru
По верстке HTML/CSS: Путь верстальщика: https://gist.github.com/codedokode/58ebc90bd006baf4b35c
MySQL: https://gist.github.com/codedokode/10539213
Слишком простые задачи? Напиши что знаешь, что хочешь изучить и придумаем тебе задачку посложнее.
Сайт опять упал!!!!! Не паникуй, а открой http://rghost.net/45000175
Не поздно ли в мои 40 становиться программистом? Ох, это будет сложно, но если ты покажешь лучшие знания, чем моложежь, то шансы есть.
Где архивы предыдущих тредов? Известно, где, на mediafire: http://www.mediafire.com/download/gza5360wdzqd743/threads-archive-pr-1..17.zip (189Мб, треды 1-17 из pr), http://www.mediafire.com/download/kgzl1f9366gc6ed/threads-archive-11..20.zip (72 Мб, треды 11-20 из b). Также один анон выложил все на дропбокс: https://www.dropbox.com/sh/4sb69jrx9qwrpcw/-nY5ia__VC (ок, он иногда не работает)
Как начать пользоваться командной строкой — gist.github.com/anonymous/9378956452c8e4a72ac8
ОП, сделай за меня мою работу или домашнее задание? — Это конечно, хорошая идея, но нет.
Расскажи про поиск работы, фриланс etc Информация о фрилансе есть в /wrk . Также, походи по сайтам вроде hh.ru, hantim.ru, geekjob, fl.ru, посмотри, поизучай ситуацию. Имей в виду, кроме фриланса, где ты 2 дня ищешь заказ, полдня обсуждаешь за бесплатно суть работы, день делаешь и еще 2 дня слушаешь от заказчика что он о тебе думает, есть удаленная работа — продаешься в рабство, и занимаешься только программированием, задачи тебе будут подкидывать наготово. Ищется по слову «удаленно» на перечисленных сайтах. Зарплата на удаленной работе может быть меньше чем в офисе в столице, но больше чем в твоей деревне. На одеске зарабатывают больше, чем на русском фрилансе.
В общем, давайте начинать уже!
Как и чем отформатировать код
Важно писать код не как попало, а аккуратно, как принято. Почему? Ну потому, что другой человек, который будет смотреть твой код, вряд ли обрадуется, когда ему придется разбирать слипшиеся строчки, разбросанные в беспорядке скобки и написанные русскими словами названия переменных. Особенно плохо будет если это, например, код тестового задания, которое ты сделал, чтобы устроиться на работу. Ты же не хочешь, чтобы тебя называли быдлокодером?
Не бойся, сделать код аккуратным совсем не сложно. Самый универсальный способ — вставить его на сайт http://phpformatter.com и нажать кнопку Format. Робот сам выровняет твой код в лучших традициях.
Если ты используешь для редактирования кода IDE, то все еще проще (а если не используешь, то почему бы не начать?):
- Eclipse PDT — жми Ctrl + Shift + F для автоматического форматирования кода.
- Netbeans for PHP — жми Alt+Shift+F
- Zend Studio — жми Ctrl + A (выделить все), затем Ctrl + Shift + F
- PhpStorm — жми Ctrl+Alt+L
- PHPDesigner — поищи нужную опцию в меню, она там есть. Или жми Ctrl + Shift + F1
- Komodo IDE — правая кнопка -> Format Using...
Вот так, нажатием одной кнопки ты можешь сделать жизнь гораздо проще.
Как видишь, c IDE жизнь может быть намного проще (еще в них есть автодополнение, автоматическая проверка кода и подсветка ошибок, навигация по файлам и функциям и много чего еще).
Основные правила
Если ты вдруг решил выровнять код вручную, запомни эти правила:
- переменные и функции пишутся с маленькой буквы, подчеркивание не используется, используется camelCase, пример: $x, $numberOfPeople, printResults()
- название функции начинается с глагола, в стиле «сделайЧтоТо»
- не знаешь английский (неужели такое бывает?) Не беда, в 21 веке есть решение этой проблемы. Не пиши транслитом, открой лучше Гугл Транслейт или slovari.yandex.ru и найди название для переменной там
- в именах классов используется CamelCase, первая буква большая, «_» может использоваться
- мы предпочитаем подстановку переменных вместо конкатенации строк: "I am $age years old" — хорошо, 'I am ' . $age . ' years old' — плохо
- мы используем для отступов 4 пробела, а не табы (нужно настроить редактор, чтобы при нажатии Tab он вставлял 4 пробела)
скобки в for и if/else ставятся так (египетские скобки):
[code]
if (...) {
// ...
} else {
// ...
}
for (...) {
// .....
}
[/code]
у определений функций и классов так:
[code]
function bakeCookies(...)
{
// ...
}
[/code]
Официальные ссылки
В PHP есть система стандартов с названием PSR. Вот стандарты, относящиеся к оформлению кода:
http://www.php-fig.org/psr/psr-1/
http://www.php-fig.org/psr/psr-2/
Как и чем отформатировать код
Важно писать код не как попало, а аккуратно, как принято. Почему? Ну потому, что другой человек, который будет смотреть твой код, вряд ли обрадуется, когда ему придется разбирать слипшиеся строчки, разбросанные в беспорядке скобки и написанные русскими словами названия переменных. Особенно плохо будет если это, например, код тестового задания, которое ты сделал, чтобы устроиться на работу. Ты же не хочешь, чтобы тебя называли быдлокодером?
Не бойся, сделать код аккуратным совсем не сложно. Самый универсальный способ — вставить его на сайт http://phpformatter.com и нажать кнопку Format. Робот сам выровняет твой код в лучших традициях.
Если ты используешь для редактирования кода IDE, то все еще проще (а если не используешь, то почему бы не начать?):
- Eclipse PDT — жми Ctrl + Shift + F для автоматического форматирования кода.
- Netbeans for PHP — жми Alt+Shift+F
- Zend Studio — жми Ctrl + A (выделить все), затем Ctrl + Shift + F
- PhpStorm — жми Ctrl+Alt+L
- PHPDesigner — поищи нужную опцию в меню, она там есть. Или жми Ctrl + Shift + F1
- Komodo IDE — правая кнопка -> Format Using...
Вот так, нажатием одной кнопки ты можешь сделать жизнь гораздо проще.
Как видишь, c IDE жизнь может быть намного проще (еще в них есть автодополнение, автоматическая проверка кода и подсветка ошибок, навигация по файлам и функциям и много чего еще).
Основные правила
Если ты вдруг решил выровнять код вручную, запомни эти правила:
- переменные и функции пишутся с маленькой буквы, подчеркивание не используется, используется camelCase, пример: $x, $numberOfPeople, printResults()
- название функции начинается с глагола, в стиле «сделайЧтоТо»
- не знаешь английский (неужели такое бывает?) Не беда, в 21 веке есть решение этой проблемы. Не пиши транслитом, открой лучше Гугл Транслейт или slovari.yandex.ru и найди название для переменной там
- в именах классов используется CamelCase, первая буква большая, «_» может использоваться
- мы предпочитаем подстановку переменных вместо конкатенации строк: "I am $age years old" — хорошо, 'I am ' . $age . ' years old' — плохо
- мы используем для отступов 4 пробела, а не табы (нужно настроить редактор, чтобы при нажатии Tab он вставлял 4 пробела)
скобки в for и if/else ставятся так (египетские скобки):
[code]
if (...) {
// ...
} else {
// ...
}
for (...) {
// .....
}
[/code]
у определений функций и классов так:
[code]
function bakeCookies(...)
{
// ...
}
[/code]
Официальные ссылки
В PHP есть система стандартов с названием PSR. Вот стандарты, относящиеся к оформлению кода:
http://www.php-fig.org/psr/psr-1/
http://www.php-fig.org/psr/psr-2/
Доброго времени суток. Хочу задать вопрос, но сначала предыстория.
Несколько моих одногруппников играют в догонялки, а я хочу сделать сайт, на котором можно будет делать ставки на них. Например, кто уйдёт водой домой. Ставки будут делаться естественно, виртуальной валютой.
Мне надо организовать:
- регистрацию пользователей с разными привилегиями;
- выбор ставки и занос в память её для определённо пользователя на определённый промежуток времени;
- всё, что касается ставки, выигрыша и проигрыша;
- и кучу всего, но об этом потом.
Дело в том, что я ничего не знаю в программировании, а учить несколько месяцев всё подряд не хочется, поэтому прошу сказать, что мне понадобится выучить. То есть, например: "Для регистрации тебе понадобится выучить (например) массивы и базы данных".
Так же хочется узнать о подводных камнях. Если кто-то уже делал подобное, то скажите, что труднее всего реализовать. Да и вообще, возможно ли такое сделать на PHP или мне перекатываться в другую ветку?
Ну и естественно, мне не нужен супер-мега-крутой сайт, который должен выдерживать большой поток людей. На него буду заходить, скорее всего, только я (под разными аккаунтами). Никаких анимаций и прочих красот мне тоже не надо.
HTML минимум знаю. PHP знаю первые уроки из оп-поста. Если я найду пример того, как делается определённая возможность, то, думаю, смогу настроить её под себя. Мне не обязательно изучать, мне можно сделать и забыть. Или это не так просто, как мне кажется?
Тогда проще всего начать с установки Апача/PHP и создания главной странички. Сделай index.phtml c html-кодом для странички, затем создай файл index.php, в котором будешь писать php-код, а пока можно просто написать require 'index.phtml'; и убедись что все работает. Дальше можешь читать мануал php про сессии и делать логин. А потом берись за базы данных чтобы хранить ставки.
Не по теме:
>Извиняюсь
Сука, да за что ты извиняешься!? Откуда эта мудацкая привычка пришла! На всех форумах, блять, они извиняются, просят прощения. Как будто без этого вопрос не спрашивается! Ну ответь мне, ну нахуя? Ты в жизни тоже перед каждым вопросом извинений просишь? Это ж унизительно, ёпт.
Да уж лучше так!
Извини, больше не буду.
Успокойся. Если хочешь что-то сказать то скажи норрмально, и желательно в каком-нибудь другом треде, а не нашем.
Пойду пробовать.
Так вот как это сделать? Я погуглил всякие exec(), shell_exec() - и не совсем пому, для разной платформы по-разному делается старт программы? Как-туда вообще путь передавать, во все примерах просто название приложения и все.
Например локальные версии сервера у всех почти на винде, а дев серве на линюхе - и стало быть код будет отличаться по разную ос?
Да, по разному. Изучай как работает bash и командная строка под линуксом.
В Windows можно попробовать команду типа start (не знаю, сработает или нет, почитай документацию на msdn), в линукс можно попробовать запускать процесс в фоне.
Убивать можно в windows через taskkill, в linux через kill.
Не знаю, как ты сохраняешь «указатель» (что это? pid?), так как команды типа shell_exec возвращают pid оболочки, а не самого процесса. Опять же, знание sh поможет тебе решить эту проблему.
И вообще, мне кажется ты зря такие вещи делаешь, тщательно не изучив теорию. Ты обрабатываешь и логгируешь ошибки при запуске? Вывод команд? Если делать кое-как, система получится ненадежная.
Алсо, мемкеш — это кеш, а не хранилище. Ты вообще по моему все что можно сделал неправильно.
Вот тебе в помощь, для начала, гайд по командной строке. Там в частности есть ответ как происходит запуск приложения из командной строки: https://gist.github.com/codedokode/10539568
Доброняш, скажи, нормален ли такой код?
http://ideone.com/qQ9eyV
И это еще так себе, иногда проверка условий у меня достигает 4-5 уровней.
Я самоучка и меня крайне смущает обилие if...else блоков, может я что-то не так делаю?
Ты правильно чувствуешь тут что-то неладное. Большая вложенность — это плохо. В таком коде надо убрать else за счет return:
if (что-то не так) {
сделать что-то;
return;
}
if (что-то еще не так) {
сделать еще что-то;
return;
}
сделать что надо;
Также, не пиши длинные простыни кода. Если в функции больше 10-30 строчек, это повод задуамться, не пора ли ее разбить. Если в классе больше 500-1000 строчек, не пора ли его разбить. Старайся писать тонкие контроллеры и толстые модели.
Задумка была такая чтобы fmap() можно было передавать функции с любым количеством аргументов, а то получается что
>return second(result);
годно только если second с одним аргументом.
Но реализовал я задумку неправильно. Перепилю.
> годно только если second с одним аргументом
Функция first (как любая функция) возвращает всегда ровно одно значение.
Массив пишется в квадратных скобках, а не фигурных. Не очень понял, что ты хотел этим сказать?
необходимо запилить какое-то подобие биржи фриланса. Работать это должно как-то так: пользователь может туда залогиниться, и просмотреть имеющиеся задания, если какое-то его устроит - взять его в работу, т.е. у остальных оно отображаться уже не будет, и взять его они не смогут.
Ну и, соответственно, надо будет еще запилить что-то вроде личного кабинета юзера - чтобы он мог смотреть взятые заказы, когда дедлайн и так далее. Загрузка файлов туда, наверное, не нужна (можно, наверное, сделать возможность загружать plain text с тегами и прочей хуйней, но это я уже потом разберусь).
Сам я в этой вашей въеб-разработке почти полный ноль, знания ограничиваются настройкой вордпресса, основами хтмл и самыми-самыми основами пхп - я знаю, например, что такое функция или цикл, но как прикрутить это все к сайту, я не знаю.
Что мне нужно сделать, чтобы запилить эту йобу?
И да, нужно, конечно же, еще какую-то админку написать, чтобы туда можно было в систему добавлять заказы (это надо парсер xls какой-то прикрутить), удалять заказы, новых юзеров добавлять, статистику выводить и так далее.
Some settings on your machine make Composer unable to work properly.
Make sure that you fix the issues listed below and run this script again:
The openssl extension is missing, which means that secure HTTPS transfers are impossible.
If possible you should enable it or recompile php with --with-openssl
Как исправить?
Он хотел сказать, что обосрался с разметкой
При этом главная страница работает нормально. В чем дело?
Win8 x64.
>>402972
Речь шла о том что
>return second(result);
Не подходит если second() функция вернет массив с количеством элементов больше 1, например
square([2,3])
вернет NaN
Криво выразился.
>return second(result);
не подходит если result это массив с количеством элементов больше 1
Хм, ну там стандартный конфиг, в котором я ничего не понимаю.
Кажется, проблема с кодировкой, ну, я предполагаю, что он не хватает кавычки в эхе и отображает все дальнейшее содержимое. Потому-что, вот, гляди, что он делает с простым примером.
Как починить?
Эм, хм. Этому файлу это помогло, а вот тому, который у меня был — нет. Видимо, дело не в кодировке.
Хм. Целый день ерундой какой-то занимаюсь.
Нет. Когда ты указываешь функции для fmap ты должен выбирать их так, чтобы то что вернула одна функция, могла исплоьзовать другая. То есть если у тебя функция возведения в квадрат, то другая должна возвращать число, а не что-то еще.
А если одна функция возвращает массив то другая должна принимать на вход массив. Если ты это не соблюдаешь то ты сам виноват что выходит ошибка.
>>403015
> return second(result);
> не подходит если result это массив с количеством элементов больше 1
Прекрасно подходит. Просто перепиши функцию second
Массив в плане возврата и передачи ничем не отличается от числа или строки:
return 5;
return 'hello';
return [2, 3, 4];
second(5);
second('hello');
second([2, 3, 4]);
Если у тебя пустые строки в начале файла до <?php то header не будет работать. Если при этом у тебя не выводится сообщения об ошибке (а должно), значит ты еще и отключил вывод ошибок, непонятно как ты в таких условиях вообще учиться чему-то собрался. Если у тебя никогда не выводятся ошибки, включи их:
В PHP по умолчанию выключено отображение ошибок в браузере, так как обычному пользователю сайта эта информация ни к чему. Но тебе, как программисту, надо видеть эти ошибки. Вот, как можно их просмотреть:
- ошибки сохраняются в лог ошибок. Можно открыть его и почитать. Если ты запускаешь код на локалхосте, у себя, то лог хранится в папке Апача (обычно она называется logs) и имеет название вроде error.log . Если на хостинге — там либо есть файл error.log либо раздел в панели управления, где лог можно посмотреть
- также, ты можешь включить отображение ошибок. Открой файл php.ini, поставь там display_errors = On и error_reporting = E_ALL и перезапусти сервер. Теперь ошибки должны выводиться на экран.
Также, ты зря называешь переменную var1. Привыкай с самого начала называть нормально, например $location или $status или $whatIsHeDoing.
> error_reporting
Вот так стоит:
error_reporting=E_ALL & ~E_DEPRECATED & ~E_STRICT
И я разобрался, кажется.
После того, как я заменил <? на <?php , то мой скрипт заработал. Вот. Кодировку еще до этого в php.ini поставил вот так, но дело не в ней:
default_charset = "UTF-8"
>>403043
> с самого начала
Ха-ха. Я уже не первый год «изучаю». Это просто я такой дурачок необучаемый.
Тогда я повторю здесь.
Оп, я начал делать задачу про клон рг хоста.
https://github.com/sqghub
Проверь пожалуйста, пока еще не поздно исправлять.
> Оп, я начал делать задачку про uppu.ru.
> С гитом особо не дружу, так что там может быть что-то не то
Вот часть замечаний (согласен, их много, но эти вещи у меня в уроках нигде не описаны, потому ты про них и не знаешь наверно):
> https://github.com/sqghub/uppu.ru/blob/master/composer.json
> name": "squiry/slim",
> "description": "First slim app",
Ты наверно скопировал файл не понимая что там задается. Ты можешь использовать его для 2 целей: 1) указать используемые зависимости 2) оформить приложение как пакет для composer (нужно если ты пишешь библиотеку и хочешь чтобы другие могли ее установить через композер)
Во втором случае там ты пишешь название твоего приложения и описание (и кто его автор). Причем ты не должен это делать, это делается только если ты хочешь чтобы твое приложение было оформлено как пакет для композера (и его можно было через него установить).
Если ты просто подключаешь внешние библиотеки, тебе хватит только ключа require. Если же ты хочешь использовать name, description, author то тогда заполни их правильными данными. После заполнения используй команду validate чтобы проверить что все верно: https://getcomposer.org/doc/03-cli.md#validate
Отсюда лучше убрать CREATE DATABASE, USE, так как я могу захотеть использовать базу данных с другим названием или несколько баз данных.
Файл composer.lock надо удалить из репозитория, закоммитить, добавить в gitignore и после этого можно вернуть обратно. Его не надо коммитить, так как он создается композером автоматически при установке и отражает ситуацию на твоей машине, и другим этот файл только помешает.
Про гитигнор: http://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#Игнорирование-файлов
В index.php отступ после <?Php увеличивать не надо (то есть перед require не нужны пробелы). Отступ во мноогих редакторах можно убрать выделив текст и нажав Shift + Tab. Также, ставь пустую строку между блоками app->get, так как иначе код слипается.
> require_once 'model/FileMapperClass.php';
> $fileMapper = new \model\FileMapperClass( );
Тут можно использовать Slim Singleton чтобы писать $app->fileMapper->doSmth(....). Документация: http://docs.slimframework.com/#DI-Overview
> FileClass
Слово Class тут я думаю, лишнее. Обычно ООП-приложение на 99% состоит из классов и писать после каждого слово «Class» — это масло масляное.
> namespace model
> {
Я советую писать namespace model; без скобок и лишнего отступа. Синтаксис со скобками испоьзуется если ты хочешь в одном файле использовать несколько неймспейсов (никогда так не делай).
> function __construct($id, $name, $type, $size, $tempName = null, $date = null)
Не очень удачная идея передавать id в конструктор, так как до сохранения в БД ты его не знаешь. Я советую либо разрешить передавать массив с значениями, либо только 2-3 обязательных аргумента, либо вообще ничего не передавать. А tempName можно и через setTempName задать.
> namespace {
> require_once 'FileClass.php';
Первый раз такое вижу. А просто написать require без плясок с неймспейсами разве нельзя? Конечно можно, ведь неймспейс в каждом файле свой. Пиши так:
namespace lalala;
require_once 'file.php';
class ....
Посмотри как пример, как неймспейсы используются в Слиме (и заодно как код оформлен) и делай так же: https://github.com/codeguy/Slim/blob/master/Slim/Slim.php
Также, не пиши длинные имена \lalala\lololo\Class, а объявляй алиас через use в начале файла.
Также, запиши себе на будущее, изучить автозагрузку классов и избавиться от require.
Папку bootstrap надо вынести из templates отдельно, например в папку styles или scripts или frontend или static еще как-то анадогично.
> <html lang="en">
Написано что я зык английский а текст на русском, почему?
> <meta name="viewport" content="width=device-width, initial-scale=1">
Понимаешь, что это делает? Если нет то выпиливай. Не должно быть ни одного тега, который ты не пониамешь.
> ?php echo "$data[appName]";?>
В шаблонах используют просто
<?= $appName ?>
Также, прочитай мой урок про XSS: https://gist.github.com/anonymous/52adda0113428b274c64
> Оп, я начал делать задачку про uppu.ru.
> С гитом особо не дружу, так что там может быть что-то не то
Вот часть замечаний (согласен, их много, но эти вещи у меня в уроках нигде не описаны, потому ты про них и не знаешь наверно):
> https://github.com/sqghub/uppu.ru/blob/master/composer.json
> name": "squiry/slim",
> "description": "First slim app",
Ты наверно скопировал файл не понимая что там задается. Ты можешь использовать его для 2 целей: 1) указать используемые зависимости 2) оформить приложение как пакет для composer (нужно если ты пишешь библиотеку и хочешь чтобы другие могли ее установить через композер)
Во втором случае там ты пишешь название твоего приложения и описание (и кто его автор). Причем ты не должен это делать, это делается только если ты хочешь чтобы твое приложение было оформлено как пакет для композера (и его можно было через него установить).
Если ты просто подключаешь внешние библиотеки, тебе хватит только ключа require. Если же ты хочешь использовать name, description, author то тогда заполни их правильными данными. После заполнения используй команду validate чтобы проверить что все верно: https://getcomposer.org/doc/03-cli.md#validate
Отсюда лучше убрать CREATE DATABASE, USE, так как я могу захотеть использовать базу данных с другим названием или несколько баз данных.
Файл composer.lock надо удалить из репозитория, закоммитить, добавить в gitignore и после этого можно вернуть обратно. Его не надо коммитить, так как он создается композером автоматически при установке и отражает ситуацию на твоей машине, и другим этот файл только помешает.
Про гитигнор: http://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#Игнорирование-файлов
В index.php отступ после <?Php увеличивать не надо (то есть перед require не нужны пробелы). Отступ во мноогих редакторах можно убрать выделив текст и нажав Shift + Tab. Также, ставь пустую строку между блоками app->get, так как иначе код слипается.
> require_once 'model/FileMapperClass.php';
> $fileMapper = new \model\FileMapperClass( );
Тут можно использовать Slim Singleton чтобы писать $app->fileMapper->doSmth(....). Документация: http://docs.slimframework.com/#DI-Overview
> FileClass
Слово Class тут я думаю, лишнее. Обычно ООП-приложение на 99% состоит из классов и писать после каждого слово «Class» — это масло масляное.
> namespace model
> {
Я советую писать namespace model; без скобок и лишнего отступа. Синтаксис со скобками испоьзуется если ты хочешь в одном файле использовать несколько неймспейсов (никогда так не делай).
> function __construct($id, $name, $type, $size, $tempName = null, $date = null)
Не очень удачная идея передавать id в конструктор, так как до сохранения в БД ты его не знаешь. Я советую либо разрешить передавать массив с значениями, либо только 2-3 обязательных аргумента, либо вообще ничего не передавать. А tempName можно и через setTempName задать.
> namespace {
> require_once 'FileClass.php';
Первый раз такое вижу. А просто написать require без плясок с неймспейсами разве нельзя? Конечно можно, ведь неймспейс в каждом файле свой. Пиши так:
namespace lalala;
require_once 'file.php';
class ....
Посмотри как пример, как неймспейсы используются в Слиме (и заодно как код оформлен) и делай так же: https://github.com/codeguy/Slim/blob/master/Slim/Slim.php
Также, не пиши длинные имена \lalala\lololo\Class, а объявляй алиас через use в начале файла.
Также, запиши себе на будущее, изучить автозагрузку классов и избавиться от require.
Папку bootstrap надо вынести из templates отдельно, например в папку styles или scripts или frontend или static еще как-то анадогично.
> <html lang="en">
Написано что я зык английский а текст на русском, почему?
> <meta name="viewport" content="width=device-width, initial-scale=1">
Понимаешь, что это делает? Если нет то выпиливай. Не должно быть ни одного тега, который ты не пониамешь.
> ?php echo "$data[appName]";?>
В шаблонах используют просто
<?= $appName ?>
Также, прочитай мой урок про XSS: https://gist.github.com/anonymous/52adda0113428b274c64
....
> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
Я советую не подключать внешние скрипты, а хранить их у себя (кроме случаев использования АПИ). Иначе ты снижаешь надежность сайта. Алсо, я вообще не уверен что там нужны эти скрипты. Они же никак не исплоьзуются? Пока можешь оставить, но позже если не используются, то надо отключить.
Также, в шаблонах у тебя много копипасты. Избавься от нее с помощью require
Если файл отсутствует надо выдавать страницу с кодом 404 (у Слима есть метод notFound( ) для этого). Неправильно когда страница ошибки отдается с кодом успеха 200. Почитай-ка: https://ru.wikipedia.org/wiki/%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2_%D1%81%D0%BE%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D1%8F_HTTP
> public function save(FileClass &$file,$dir)
Объекты и так передаются (почти как) по ссылке, всегда. Мануал: http://php.net/manual/ru/oop5.intro.php
Заметь что разница в наличии/отсутствии & все же есть.
Если ты не используешь & то ты можешь менять переданный объект, но не можешь поменять на какой объект указывает переменная.
Если ты исплоьзуешь & то ты можешь менять и переданный объект, и записать что-то другое в исходную переменную: $file = 1; Естественно, это плохо в 99% случаев и делает код запутаннее потому стоит убрать &.
Насчет генератора в функции public function getLast, не уверен что это надежно. В PDO ты не можешь выполнять следующий запрос пока не прочитал все результаты предыдущего, а с генератором такая ситуация может легко возникнуть. Потому используй лучше тут fetchAll и обычный массив.
В общем, замечаний много, но это в первую очередь из-за того, что нигде толком в одном месте эти советы не собраны и приходится практически каждому, кто делает файлообменник, это все рассказывать. Надо будет потом собрать это в урок.
Пока у тебя неплохо получается.
https://github.com/sqghub/uppu.ru/blob/master/model/FileMapperClass.php#L48
> unset($db);
Зачем это?
> $db = new DataBaseClass( );
Лучше передавать db в конструктор FileMapperClass. Тут длинная и сложная паста, пытающаяся объяснить почему (если кратко: чтобы можно было передавать туда разные классы): https://gist.github.com/codedokode/e1d31a31b37d5f635057
На тебя наверно сегодня много новой информации вылилось, ну не беда, привыкай, тяжела и неказиста жизнь простого программиста. То ли еще будет.
Yii или Симфони + ООП + базы данных. То есть тебе надо довольно много изучить. И задача тоже большая, так что сделать быстро не рассчитывай.
>>402955
Какая ОС? Линукс небось? Что если сделать php-файл c кодом
<?php phpinfo( );
открыть его в браузере и поискать там слово ssl?
Если под линуксом, сделай php -i | grep ssl
Нет ли ошибок типа «не могу загрузить библиотеку» при запуске Апача?
А display_errors чему равно? Ты проверил? Не проверил же.
Советую error_reporting = E_ALL (показывать все ошибки)
display_errors = On (отображать ошибки в браузере, никогда не делай так на боевом сайте)
необъяснимо, но факт: передаются через гет параметры, во всех браузерах нормально, а вот в ие исчезает пробел между значением и единицей измерения, из-за этого не выполняется условие. что за нахуй? в 9м всё нормально, только в 11. дело в том, что там параметр с неверной кодировкой передается и его потом на этой странице преобразовываю я в нужную. думаю что-то связанное с этим. может кто знает этот заскок интернет эксплорера?
Ты что-то делаешь неправильно скорее всего. Покажи здесь кусок адресной строки, как есть, с этим пробелом
> дело в том, что там параметр с неверной кодировкой передается и его потом на этой странице преобразовываю я в нужную.
Передавай в правильной
есть таблица вида
школа - класс - ученики
в школе 5 классов, в классе ученики
я хочу сделать форму редактирования, чтобы менеджер не доёбывал меня а правил это сам
посоветуй какой-нибудь плагин, чтобы вё было перед глазами, чтобы можно было на одной странице сразу и править и смотреть
>На тебя наверно сегодня много новой информации вылилось, ну не беда, привыкай, тяжела и неказиста жизнь простого программиста. То ли еще будет.
Далековато еще до простого программиста.
В шаблонах у меня и есть копипаста из примера бутстрапа. С пространствами имен у меня ругался почему-то, хотя может и не из-за них. Ну и композер на файл с только рекваир ругался. Про генератор и запросы: я и хотел массив получить на выходе, но у меня что-то не вышло, а соображал к утру уже нехорошо и я не нашел ничего лучше, чем раскрутить его генератором. И в сохранении файла айди обратно не передавался без амперсанта. Остальное исправлю вечером-ночью, наверное.
Если брать Yii то: ActiveRecord, формы, валидация, миграции БД, авторизация, из того что сразу вспоминается.
Плюс много готовых сторонних плагинов.
> Разбирателя адресов и вывода шаблонов же хватает.
Это пока.
бамп
может кто-нибудь знает коллекцию готовых круд-плагинов, если их можно так назвать конечно
Какая таблица? Где она хранится? SQL? Запили какой-нибудь phpmyadmin и пусть редактирует прямо там.
таблица это чтобы вы поняли о чём речь
нет, они явно не будут учить скл или сидеть в пхпмуадмин, они скажут мне поправить, это же я обезьяна работающая за чуть меньше чем среднюю зп по россии, а не они
Хули там учить, зашел в phpmyadmin и сиди редактируй как в екселе.
Либо ищи аналог http://www.blingblocks.org/en/ и пердолься с ним. Я такое точно видел на джаваскрипте, не помню как называется.
хуета
при ховере ничего не выпадает, хотя обещают, перемещать блоки с шифтом не могу
и вообще ты нихуя не понял
что я хочу: пикрилатед
три категории, в каждой элементы
нужно чтобы пользователь по клику на элементе мог переименовать его, удалить, добавить новый, таскать между категориями
сейчас оп придёт и скажет что я бы быстрее написал сам, но практика показывает что я сам пишу ебаное говно
Вряд ли ты найдешь готовую коллекцию круд плагинов под это дело. Самому такое писать, впрочем, недолго – добавил в круд нужных ajax'ов по клику и драг'н'дропу и готово.
вот именно делать это, выстроить в колонки, написать добавление, удаление блоков, отловить миллиард случаев когда оно не работает - займёт у меня столько времени, что я лучше вручную буду править
делал уже такое
почему может быть, что переменные не проходят условие == , если они одинаковы?
их вар дампы:
string '34-50см.' (length=8)
string '34-50cм.' (length=8)
в чем может быть дело?
>выстроить в колонки
>добавление
>удаление блоков
Так это же все из коробки любого круд-фрейморка есть.
>отловить миллиард случаев когда оно не работает
Миллиард случаев на три колонки с одной связью? Там же твоего кода всего 5 строчек будет.
>там мне не нравятся сами плагины
Там это где? И какие плагины? Насколько я понимаю, никакие плагины не нужны. Drag'n'drop нативно поддерживается в html5 (а можно и без него для начала), а все крудодействия уже есть в фреймворке.
они имеют такой вид благодаря xdebug
почему может быть, что переменные не проходят условие == , если они одинаковы?
их вар дампы:
string '34-50см.' (length=8)
string '34-50cм.' (length=8)
в чем может быть дело?
> var_dump(bin2hex($a));
> var_dump(bin2hex($b));
а вот так не одинаковы
string '33302d3436f1ec2e' (length=16)
string '33342d353063ec2e' (length=16)
хмхмхм, не пойму, визуально они абсолютно одинаковы. и тип тот же
Любой фреймворк. Symfony, Yi, whatever – я в php не шарю, мимокрокодил.
С нуля сейчас никто ничего не пишет. Разве что задачки уровня этого треда решать для лучшего понимания языка.
Смотри, каждые две 16-х цифры это один байт. То есть если добавить пробелы будет
33 30 2d 34 ...
Каждый байт тут соответствует 1 символу (код символа зависит от кодировки, если у тебя win-1251 то вот таблица: http://msdn.microsoft.com/ru-RU/goglobal/cc305144.aspx )
Например 33 — это цифра 3, 2d — это минус и т.д.
Сравни байты и увидишь какие символы различаются. Скорее всего ты просто не заметил что они разные.
Ты вообще странный какой-то, строки сравнивать с помощью этой функции. Тебе надо внимательно читать мануалы а не подставлять функции наугад.
Алсо, функция mb_detect_encoding в принципе не работает почти никогда.
В данном случае, разбей строки на байты как я написал, найди различающиеся байты и посмотри каким символам они соответтствуют.
никто их не сравнивал. я проверял ей кодировку первой и второй переменных, одинаковы ли кодировки.
что значит нет?
string '34-50см.' (length=8)
string '34-50cм.' (length=8)
может ты увидишь разницу? а то мне не очень заметно
>почему может быть, что переменные не проходят условие == , если они одинаковы?
ответ - они не одинаковы
что ты ещё хочешь?
да ясное дело, что не одинаковы, раз не проходят условие. я уточнил потом, что считаю их одинаковыми только визуально.
а вообще-то, я писал сюда узнать, в чем может быть дело, почему визуально одинаковые переменные на самом деле не одинаковы.
почему ты такой пиздопротивный?
Дропай свой самодельный фрейморк и выбирай из уже написанных. Там все есть и сделано гораздо удобнее.
>почему визуально одинаковые переменные на самом деле не одинаковы.
вот смотри
стоит бэйли в юбочке
рядом стоит твоя еот
внешне они одинаковы
но внутри...
понимаешь о чём я?
ты же не спрашиваешь почему они не одинаковы, хоть и выглядят как девочки
>>403148
в понедельник приду к начальнику и скажу - на дваче сказали переносить проект на новый фраемворк
ты хочешь сравнить визуально строки, и сравниваешь при помощи == ?
== сравнивает внутренность, а не визуальное. поэтому ты получаешь то что получаешь
первая ошибка которую я вижу - почему ты передаёшь 34-50см.
почему не 34-50? если тебе нужны разные единицы измерения - сделай фиксированный список
mb_detect — не волшебная палочка которая может определить кодировку. Кодировку в общем случае вообще определить невозможно (так как ты имеешь только набор байт — как ты поймешь, что ими закодировано?), но если речь идет о тексте, можно определить статистическими методами (предположив например что в тексте содержатся в основном буквы а не значки и закорючки и выбрав те кодировки, в которых часто встречающиеся коды совпадают с буквами), но mb_detect их не реализует.
Вместо этого она наугад выбирает одну из нескольких заложенных кодировок. Статья: http://habrahabr.ru/post/107945/
В твоем случае, кодировка скорее всего win 1251. То, что строки разные, видно невооруженным глазом по кодам символов.
Хватит ругаться. Посомтри на коды символов и сопоставь их с таблицей по ссылке. Ты ошибся когда дампил переменные, скорее всего сдампил одну и ту же 2 раза.
И конечно, переменные выглядящие одинаково могут быть внутри не одинаковы. Например, есть русские и латинские буквы, совпадающие по виду. Есть пробел и неразрывны пробел, в юникоде вообще есть невидимые пробелы, составные символы (́ + a = ́a) и прочие радости.
Умный человек естественно в таком случае будет использовать готовую библиотеку типа ICU.
В твоем случае виновата невнимательность, а не похожие символы.
Только буква с, буква м выглядит в разных языках по-разному. Но у него еще и цифры разные, если ты на коды посмотришь. Сам ты тугой.
ну блять =(
Посмотри внимательно на название в мануале http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-add
Алсо, вместо DATE_ADD можно еще писать так:
x + INTERVAL 3 DAY
всем спасибки
Нет значит напиши сам. Enjoy your bicycle. Обычно в таких случаях рекомендут Twitter Bootstrap для интерфейса, хотя я на него уже смотреть не могу.
Ну или погугли, может что найдешь.
>в понедельник приду к начальнику и скажу - на дваче сказали переносить проект на новый фраемворк
>переносить проект
>таблица из трех сущностей
Охлол, какой проект? Что твой проект делает? Выводит данные из двух таблиц? То что ты хочешь пишется за 5 часов джуниором и за неделю человеком который в программирование месяц назад вкатился. А вывести данные из двух таблиц это вообще дело пяти минут.
>год пилю его
>заполняю sql-таблицы вместо менеджера
>не могу создать простейший круд
>я обезьяна работающая за чуть меньше чем среднюю зп по россии
Ты на своем месте!
Аноны, я сделал урок из серии задачек под названием «Путь верстальщика». Решая эти задачки, ты изучишь разные аспекты CSS, а в конце сверстаешь макет сайта. Заходи, изучай: https://gist.github.com/codedokode/58ebc90bd006baf4b35c
>>403096
Разбиратель адресов называется роутер.
>>403192
Так, давай полегче. Нечем помочь анону — топай по своим делам.
>>403183
да, иногда захожу
А насколько хорошо вообще пхп макаке нужно знать ксс и хтмл? Я всегда думал, что пхп кодер только функционалом занимается и внешний вид вообще не трогает.
пхп-программист только бэкенд пилит
пхп-макака пилит дизайн, вёрстку, бэкенд, фронтенд, лижет жопу менеджерам, и вручную правит данные в бд
всё кроме третьего пункта выброси и скажи мне что не так? моя вина в том что мне не дают времени пилить админку и требуют функционал?
>пыхоигр
Это как? Как на пхп можно сделать что-то интерактивное, там ведь данные обновляются только при обновлении страницы?
>>403200
им дали доску для вопросов о серверах
https://2ch.hk/srv/
нет, не хотим, хотим спрашивать в рандом треде
Это нам рассказывает господин не-могу-слепить-простейший-круд.
>>403199
>всё кроме третьего пункта выброси и скажи мне что не так?
А зачем третий пункт выбрасывать? Мне сначала показалось что ты это ты так жалуешься – программиста заставляют таблицы редактировать вместо менеджера, ну думаю надо помочь, узнать в чем проблема. А оказывается что все нормально – автоматизировать задачу ты не хочешь/не можешь и остается только заниматься работой уровня "оператор пека".
>моя вина в том
Я не знаю в чем твоя вина – про проект ты ничего не рассказываешь, а из того что ты пояснил в начале ясно только то, что проект состоит из двух таблиц и проектом это можно назвать с натяжкой.
>мне не дают времени пилить админку
Охлол, админку пилить не дают, а заполнять хуиту вместо менеджера дают. Это работа оператора пека, не программиста. Опять же, из того что я понял – подобная админка делается за 5 часов, поэтому не понятно какого такого времени не дают. Ты же все это время на двачах сегодня просидел. На двачах начальник дает сидеть? Какой функционал требует? Еще одну таблицу добавить?
>Я не знаю в чем твоя вина
ну так не кудахтай тогда
вопрос был про готовые штуки уровня http://www.jeasyui.com/index.php
Лучше знать чем не знать. Смотри, какие у меня мысли по этому поводу:
— веб-технологии простые. Нет никаикх проблем изучить фронтенд и бекенд. Если человек не хочет, то скорее всего он просто ленив
— есть понятие «full-stack dev» то есть разработчик который знает и фронтенд и бекенд, разумеется он ценится больше
— даже если ты бекендщик, тебе может понадобиться что-то поправить в выводе данных, не отвлекать же фронтендщиков ради этого
То есть знать на уровне «поправить верстку» точно надо, а лучше знать на хорошем уровне. Мой курс задачек «Путь HTML» как раз ведет тебя к хорошему уровню.
>Когда ты указываешь функции для fmap ты должен выбирать их так, чтобы то что вернула одна функция, могла исплоьзовать другая. То есть если у тебя функция возведения в квадрат, то другая должна возвращать число, а не что-то еще.
Я понимаю, но я хотел переписать fmap так, чтобы это не имело значения. Я понимаю что этого нет в задании, просто мне стало интересно.
>Прекрасно подходит. Просто перепиши функцию second
Вопрос не в возврате, а в функции. пикрелейтед.
Еще раз: я для себя, из чистого интереса, захотел переписать fmap так, чтобы можно было передать ей в качестве аргументов функции, ожидающие любое количество аргументов.
Не очень понятно, зачем там нода если интерпретатор JS есть в Chromium. Надеюсь у них хватило ума не строить там клиент-серверную архитектуру с аяксом.
— запускается медленное, первый запуск секунд 8. После Sublime непривычно
— русский шрифт ужасный и буквы идут с огромными пробелами между ними
— менеджер расширений притормаживает при переключении вкладок. Не удивлюсь если там какой-нибудь новомодный js-шаблонизатор использован
— иконки в SVG, не знаю, влияет ли это на скорость работы, по идее с ними должно работать медленнее, не знаю правда сильно или нет.
— похоже что для отображения окна редактирования используется небыстрый codemirror
— main.js весит 4.5 Мб: как-то страшновато
— прокрутка не плавная, а дерганая, может из-за моей ОС
— привычных вкладок нет
— есть ощутимый лаг где-то в полсекунды при открытии/закрытии файла. Непривычно после Sublime
— в проекте должен быть index.html иначе часть функций не будет работать
— Ctrl + PgUp/PgDn не переключает окна
— шрифт по умолчанию мелкий
— сделали свое (сомнительное) автодополнение, вместо Emmet или Hayaku
— нужны права администратора для установки, нельзя просто распаковать zip архив в любую папку.
— PHP файлы никак не поддерживаются
— ссылки в js-шаблонах вида include 'header.jhtml' не распознаются
— не показывается полный путь к файлам при наведении на них
Памяти потребляет 100 Мб при одной открытой вкладке. На проекте среднего размера — 250 Мб.
Пожалуй, единственная непоправимая тут проблема, на мой взгляд — это codemirror. Любой нормальный верстальщик знает что тяжелое DOM-дерево вряд ли будет хорошо работать, и это тот случай. Лучше бы они конечно редактор и раскрашивалку кода сделали на более быстрых технологиях. Остальное все можно допилить и оптимизирвать (ну и насчет времени запуска не уверен).
Из плюсов можно отметить:
— обещаемый Адобом плагин для создания CSS кода на основе PSD-макета
— удобный интерфейс для inline редактирования CSS свойств. Например для цвета открывается панелька выбора цветов, для анимаций — график изменения значения. Все это доступно по Ctrl + E.
— интересные интерфейсные рещения, когда например можно из одного файла заглянуть в другой. Например ты можешь кликнуть на тег, нажать Ctrl + E и прямо тут же раскроется кусочек css файла со стилями, применяемыми к этому тегу. Удобно! Это отличное интерфейсное решение (раньше обычно такие вещи открывались в отдельной панели которая отнимает экранное место и требует перемещать взгляд).
— проверил Ctrl + E на имени класса в большом проекте с огромным CSS, работает нормально. Правда для тега input показывает правило input.some-class которое к нему не относится
— говорят что поддерживает Live Preview то есть ты открываешь страницу в Хроме, праавишь в редакторе и она обновляется в браузере. Если у тебя 2 монитора то достаточно просто повернуть голов чтобы увидеть изменения, не надо жать Ctrl + S и F5. Наверно, это удобно. Если у тебя 3 монитора то на третьем можно открывать Dev tools вдобавок.
— есть быстрое открытие как в саблайме по Ctrl + Shift + O
— говорят, автодополняет имена файлов, например картинок
— умное автодополнение для JS: у меня он как-то умудряется показывать методы для объектов, определенных в другом файле
— есть просмотр картинок, без масштабирования и довольно бесполезный
— есть JSLint, но лучше бы JSHint, к тому же у него настройки не очень адекватные: требует от меня включить строгий режим например
Кто занимается версткой, попробуйте этот редактор. чтобы открыть проект, просто перетащите папку с файлами на окно.
Хабр:
http://habrahabr.ru/post/190454/
http://habrahabr.ru/post/242297/
Не очень понятно, зачем там нода если интерпретатор JS есть в Chromium. Надеюсь у них хватило ума не строить там клиент-серверную архитектуру с аяксом.
— запускается медленное, первый запуск секунд 8. После Sublime непривычно
— русский шрифт ужасный и буквы идут с огромными пробелами между ними
— менеджер расширений притормаживает при переключении вкладок. Не удивлюсь если там какой-нибудь новомодный js-шаблонизатор использован
— иконки в SVG, не знаю, влияет ли это на скорость работы, по идее с ними должно работать медленнее, не знаю правда сильно или нет.
— похоже что для отображения окна редактирования используется небыстрый codemirror
— main.js весит 4.5 Мб: как-то страшновато
— прокрутка не плавная, а дерганая, может из-за моей ОС
— привычных вкладок нет
— есть ощутимый лаг где-то в полсекунды при открытии/закрытии файла. Непривычно после Sublime
— в проекте должен быть index.html иначе часть функций не будет работать
— Ctrl + PgUp/PgDn не переключает окна
— шрифт по умолчанию мелкий
— сделали свое (сомнительное) автодополнение, вместо Emmet или Hayaku
— нужны права администратора для установки, нельзя просто распаковать zip архив в любую папку.
— PHP файлы никак не поддерживаются
— ссылки в js-шаблонах вида include 'header.jhtml' не распознаются
— не показывается полный путь к файлам при наведении на них
Памяти потребляет 100 Мб при одной открытой вкладке. На проекте среднего размера — 250 Мб.
Пожалуй, единственная непоправимая тут проблема, на мой взгляд — это codemirror. Любой нормальный верстальщик знает что тяжелое DOM-дерево вряд ли будет хорошо работать, и это тот случай. Лучше бы они конечно редактор и раскрашивалку кода сделали на более быстрых технологиях. Остальное все можно допилить и оптимизирвать (ну и насчет времени запуска не уверен).
Из плюсов можно отметить:
— обещаемый Адобом плагин для создания CSS кода на основе PSD-макета
— удобный интерфейс для inline редактирования CSS свойств. Например для цвета открывается панелька выбора цветов, для анимаций — график изменения значения. Все это доступно по Ctrl + E.
— интересные интерфейсные рещения, когда например можно из одного файла заглянуть в другой. Например ты можешь кликнуть на тег, нажать Ctrl + E и прямо тут же раскроется кусочек css файла со стилями, применяемыми к этому тегу. Удобно! Это отличное интерфейсное решение (раньше обычно такие вещи открывались в отдельной панели которая отнимает экранное место и требует перемещать взгляд).
— проверил Ctrl + E на имени класса в большом проекте с огромным CSS, работает нормально. Правда для тега input показывает правило input.some-class которое к нему не относится
— говорят что поддерживает Live Preview то есть ты открываешь страницу в Хроме, праавишь в редакторе и она обновляется в браузере. Если у тебя 2 монитора то достаточно просто повернуть голов чтобы увидеть изменения, не надо жать Ctrl + S и F5. Наверно, это удобно. Если у тебя 3 монитора то на третьем можно открывать Dev tools вдобавок.
— есть быстрое открытие как в саблайме по Ctrl + Shift + O
— говорят, автодополняет имена файлов, например картинок
— умное автодополнение для JS: у меня он как-то умудряется показывать методы для объектов, определенных в другом файле
— есть просмотр картинок, без масштабирования и довольно бесполезный
— есть JSLint, но лучше бы JSHint, к тому же у него настройки не очень адекватные: требует от меня включить строгий режим например
Кто занимается версткой, попробуйте этот редактор. чтобы открыть проект, просто перетащите папку с файлами на окно.
Хабр:
http://habrahabr.ru/post/190454/
http://habrahabr.ru/post/242297/
> Я понимаю, но я хотел переписать fmap так, чтобы это не имело значения.
Ты можешь сделать, но это крайне дурная идея.
Можно проверять тип который вернула функция и если это массив, вызывать ее по-другому.
Но это крайне дурная идея и быдлокод, на мой взгляд. Так как тебе труднее становится понять, что будет передано в том или ином случае. Да и как можно надежно писать код, если тебе может придти то один аргумент, то несколько.
Функции должны принимать и возвращать данные одного типа. Не должно быть такого, что функция может вернуть массив или строку в зависимости от настроения. Или принимает массив или строку. Это усложняет код, затрудняет понимание и создает баги.
> Я понимаю, но я хотел переписать fmap так, чтобы это не имело значения.
Можно проверять тип который вернула первая функция и если это массив, вызывать вторую функцию по-другому, с несколькими аргументами. То есть добавить один if.
>> $remains > 0)
>Вместо того чтобы раза 4 это повтрить, можно просто поставить условие «если остаток ноль, выходим из функции»
А как это делать? через if + return или через if + die() ?
http://ideone.com/nWKYrS
Вот пока переделал функцию smallNumbers()
теперь она хороша?
Дополнения:
— extract не хочет открывать PSD c диска а требует зарегистрироваться и загружать их в облако. Как насчет нет? (подозреваю, Адоб просто не хочет отдавать парсер PSD файлов в открытый доступ)
— если открыть 80 Кб HTML файл, прокрутка тормозит
+ можно перейти к определению функции по Ctrl + J
Да, я знаю. Алсо, live previewили как оно там отрубается в нем, если открыть в браузере developer tools
Я тут конкретно застопорился.
Вот пока над этим думаю.
- ошибки в расписании (фильмы накладываются друг на друга), отсортированные по возрастанию времени
Дай подсказку. Как в одном запросе получить две разные таблицы. И сравнить их поля.
Я пока не умею учится сам и искать ответы(
1.Формируешь вопрос
2.идешь на translate.google.ru , переводишь
3.гуглишь перевод
4.???
5.профит
Опционально можно гуглить на русском, но это в перспективе тупиковый путь
Ты на верном пути, но пока все неправильно. И у меня ощущение что ты пытаешься решить задачу подбором, так ты ничему не научишься. Надо тщательно подумать, как и что мы с чем объединяем, какие таблицы в первую очередь, а какие присоединяем потом для вывода дополнительной информации.
Во-первых, давай начнем с вопроса: даны 2 отрезка, a1 ... b1 и a2 .. b2, при каком условии они пересекаются? напиши формулу.
Во-вторых, правильно ли ты вычисляешь время конца фильма? У тебя в обоих случаях прибавляется одна и та же длительность к s1 и к s2.
Дальше, зачем группировка? Группировка обычно используется вместе с аггрегатными функциями, но я у тебя ни одной не вижу.
Дальше, почему используется LEFT JOIN на s2? Какой он смысл тут имеет?
Почему первой идет таблица film? Ты что ищешь в первую очередь? Пересечения в расписании или фильмы?
Посмотри внимательно на условие: найти пересечения в расписании. В мире SQL для этого обычно делается джойн таблицы на себя, с дальнейшим отсеиванием не подходящих записей по условию. А после этого ты можешь приджойнивать таблицы для выборки дополнительной информации.
И выводить лучше в другом формате, писать какой фильм с каким пересекся, а у тебя это непонятно, так как выводится всего одно название.
Подсказка: что бы решить вот это
> даны 2 отрезка, a1 ... b1 и a2 .. b2, при каком условии они пересекаются? напиши формулу.
можно попробовать сначала написать условие когда отрезки не пересекаются, и перевернуть его.
По поводу id билетов, который int и auto_increment: максимальный размер int не unsigned 2147483647, в среднем в день хороший кинотеатр дает 40 сеансов, остается 53687091, в зале около 100 мест, остается 536870, залов где-нибудь штуки 4, остается 134217, дней 365, получается в итоге, что id хватит на 367 лет. Это не порядок! Внести как минимум unsigned
Бесполезный совет, так как в гугле нет решения этой задачи скорее всего, а гугл транслейт может сильно исказаить смысл вопроса.
>>403246
>if (varTmp instanceof Array) {
Это ненадежно, так как если массив создан в другой вкладке или ифрейме (это возможно если secondArgFunc была там создана) то там свой window и свой window.Array (в каждой вкладке и ифрейме работает своя копия яваскрипт-машины со своими копиями функций и объектов, включая window, document и все глобальные стандартные объекты). И условие instanceof не сработает.
Вот пример, поясняющий это:
function Array1() {} // представим что это window.Array в одном окне
function Array2() {} // а это в другом
var a = new Array1( );
a instanceof Array1; // true
a instanceof Array2; // false
Array1 == Array2; // false
Потому для проверки на массив используют другой способ. Какой? В новых браузерах есть метод для этого, а для старых пишется хитрый хак: https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
Функция isArray встречается во многих библиотеках, например, loadsh или jQuery.
В остальном верно.
Бесполезный совет, так как в гугле нет решения этой задачи скорее всего, а гугл транслейт может сильно исказаить смысл вопроса.
>>403246
>if (varTmp instanceof Array) {
Это ненадежно, так как если массив создан в другой вкладке или ифрейме (это возможно если secondArgFunc была там создана) то там свой window и свой window.Array (в каждой вкладке и ифрейме работает своя копия яваскрипт-машины со своими копиями функций и объектов, включая window, document и все глобальные стандартные объекты). И условие instanceof не сработает.
Вот пример, поясняющий это:
function Array1() {} // представим что это window.Array в одном окне
function Array2() {} // а это в другом
var a = new Array1( );
a instanceof Array1; // true
a instanceof Array2; // false
Array1 == Array2; // false
Потому для проверки на массив используют другой способ. Какой? В новых браузерах есть метод для этого, а для старых пишется хитрый хак: https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
Функция isArray встречается во многих библиотеках, например, loadsh или jQuery.
В остальном верно.
> задачка номер 5
Отступы зачем такие конские ставить? Перекосилось же все.
> for(i = 1; i< boundArgs.length; i++) args.push(boundArgs);
> for(i = 0; i< arguments.length; i++) args.push(arguments);
После for надо всегда стаивть { }
Также, тут есть другой способ, не знаю, короче он или нет. Псевдомассив arguments можно преобразовать в массив с помощью
var a = Array.prototype.slice.call(arguments);
А потом склеить массивы через concat. Можешь попробовать сделать, чтобы было без циклов.
> return self.apply(func, args);
Почему в качестве this передаешь func?
>Можешь попробовать сделать, чтобы было без циклов.
Ок, попробую
>Почему в качестве this передаешь func?
Упустил, можно было просто this
А так, принцип решения верный.
>>403290
Ну с unsigned хватит не на 367, а на 720. Разница невелика. Надо брать 64-битный bigint.
Кстати, не знаю какие номера у билетов в кино, но автобусные например как-то 6 цифрами обходятся. А ведь там людей ездит больше чем в кино ходит. Правда, они их в базе и не хранят.
Но замечание справедливое. Анон, который делает задачу, поставь BIGINT на всякий пожарный (и в будущем учитывай такие вещи), а то ведь придется в 2380 году переделывать систему.
Спорно
>так как в гугле нет решения этой задачи скорее всего
так я и не говорил гуглить решение задачи, я сказал гуглить вопрос
>гугл транслейт может сильно исказаить смысл вопроса.
гугл транслейт не панацея, надо смотреть же что получается.
Я просто к тому, что гуглить на английском гораздо эффективнее
Этот трюк со slice много где используется, так что надо чтобы тебя он не удивлял. По сути это вызов метода slice от массива, только вместо массива мы в качестве this передаем псевдомассив, и внезапно все работает.
хочу использовать их в паре классов (перемещё туда дублирующийся метод)
в гугле есть мнение что трейты - плохо
что ты думаешь о них?
В общем, гугл прав. Трейты позволяют избавиться от копипаста методов, но вопрос «а нафига в разные классы добавлять один и тот же метод?» остается. И с вероятностью 99% ты что-то делаешь неправильно.
Например, может быть надо вынести методы в отдельный объект (объекты) и передавать его в те классы ,где он нужен?
тащемта да, от трейта можно избавится
1. Определить, сколько раз в тексте встречаются заданные слова.
2. Найти дубли в тексте (по строкам, а не словам).
3. Найти уникальные строчки.
4. Сравнить два текстовых файла и показать, чего нет в первом, что есть во втором — и наоборот.
>предлагает больше заданий на регулярки
просто иди нахуй, окда?
Лучше вписать больше заданий в циклы, массивы и строки, а самое главное в функции. А то 1 задание на функции вообще не круто, у меня оно вообще не вызвало понимание как должна функция работать и как их правильно составлять.
>предлагает больше заданий на элементарщину, которую можно почерпнуть из книг
Лучше вписать статью по кодировкам.
Потому что там по php три задания уровня: "Впишите в пропущенном коде программу букву $a. Какой же ты молодец! А теперь повтори с тремя буквами. Ой как классно! Теперь ты знаешь php!"
Да ну ладно, там есть и циклы и массивы, и даже классы.
>1 задание на функции вообще не круто
Сложилось такое же впечатление.
>Лучше вписать больше заданий в циклы, массивы и строки, а самое главное в функции.
Это не противоречит тому, что я предлагаю. Анончик не решит подобную задачку без знаний погроммирования. Это сэкономит в будущем кучу времени.
Заметь, что на написание этого говнокода у меня ушло около половины дня, а к самой идее, методом проб и перебора приходящих в голову вариатнтов, я потратил не один день.
(Если твой ответ будет отрицательным, не обязательно его аргументировать)
Хитро придумано, ведь ты знаешь, что оп по доброте душевной никогда не скажет тебе, что ты даун. Тебе нужно было спросить в прикрипленном треде, хотя там твой код не стали бы читать, тебя бы назвали дауном авансом уже за то, что ты пишешь на пыхе.
>стоит ли мне продолжать
Зачем ты ищешь поддержку во вне, а не внутри? Вон школьники сейчас почувствуют твою неуверенность, ради лулзов в душу наплюют.
>прямо в лицо
Если код решает твою задачу, то совершенно насрать, что и как ты там написал.
>Если код решает твою задачу, то совершенно насрать, что и как ты там написал
пхп-стайл во всей красе
когда его пидорнут (а он же собирается работать пхп-программистом?) и следующая макака сядет на его место - она просто блядь охуеет и сядет писать заново, тратя деньги заказчика, причем писать по принципу
>Если код решает твою задачу, то совершенно насрать, что и как ты там написал
в итоге замкнутый круг и пхп-программистов считают дном
>вызвало понимание как должна функция работать и как их правильно составлять
садись читай "макконела - совершенный код"
прошу опа добавить книгу в шапку - это лучшее что я читал по программированию
макконел - совершенный код
молодец, можешь не продолжать
Оп, я вроде бы пофиксил, на что ты уговорил. Только вопрос про конструктор класса файлов остался.
>Не очень удачная идея передавать id в конструктор, так как до сохранения в БД ты его не знаешь. Я советую либо разрешить передавать массив с значениями, либо только 2-3 обязательных аргумента, либо вообще ничего не передавать. А tempName можно и через setTempName задать.
Можешь объяснить подробнее? Я не понимаю в чем смысл.
>Потому для проверки на массив используют другой способ. Какой? В новых браузерах есть метод для этого, а для старых пишется хитрый хак:
Подправил. http://jsfiddle.net/81n7yn73/2/
>>403298
>Также, тут есть другой способ, не знаю, короче он или нет.
Запилил: http://jsfiddle.net/jnr1ctbb/
очепятка: привзяать контекст
Задачка №6: http://jsfiddle.net/eutonLL3/
>в итоге замкнутый круг
Я раньше любил совершенствовать код, часами всматривался, упрощал, приводил в порядок абзацы. Сейчас понял, что нинужна тратить время на рефакторинг, когда и всё так работает.
у тебя одни крайности? либо часами всматриваться в код, либо
>совершенно насрать, что и как ты там написал
?
>деньги заказчика
Так говоришь, будто тратить деньги заказчика это что-то плохое.
Если ты начинающий говнокодер, то сколько бы ты не всматривался в код, лучше он от этого практически не станет – в силу того что у тебя нет нужного опыта и косяков ты не заметишь. Тут главное не писать совсем уж хуйню, уметь вовремя сказать себе – да это же пиздец и лапша.
пхп-программистов считают дном, потому что это самый распространенный и дешевый язык в вебе. Куча проектов делается на вордпрессоджумлах, заказчик чаще всего в погромировании не шарит и проект контролировать не в силах, поэтому говнокодер волен писать что ему в голову взбредет.
А через год проект уже либо развалится, потому что нахуй не нужен; либо перерастет во что-то крупное и его в любом случае придется переписывать, т.к. никакой джуниор нормальный хайлоад спроектировать не в состоянии; либо остается в том состоянии в котором был, и его иногда подсаживают на новые костыли и хаки другие говнокодеры, которые пришли на ту же самую днищезарплату к похуисту-заказчику.
Сам так делаю. Тут наговнокодил, там наговнокодил, каждый новый проект на новом стеке технологий (одно и то же было скучно задрачивать), иногда остаешься на нормальных проектах, но недолго, говнокодер же. Денег мало, зато фриланс и угара много.
вся суть пхп-макаки
вместо того чтобы на рабочих проектах оттачивать скиллы, советы по проектированию из книг, и затем через пару лет перекатится на норм язык ты дохуя времени пишешь говно и оправдываешься тем что угара много?
ну пиши до 40 лет когда тебя просто буду нахуй нахуй
не понял вопроса
речь о говнокоде
причём тут php?
про недостатки языка тебе ответит гугл миллионом статей, в том числе тысячами - переведёнными, в том числе парой на хабре с обсуждением
>причём тут php?
>перекатится на норм язык
>про недостатки языка тебе ответит гугл миллионом статей
Ясно
>пхп-программистов считают дном, потому что это самый распространенный и дешевый язык в вебе
цель переката но норм язык - получать много денег
если тебе платят много за пхп - никаких проблем
>дохуя времени пишешь говно
Проблема в том, что когда ты только начинаешь писать говно – ты еще не знаешь что это говно. Говном оно становится через пару месяцев активной работы, когда заказчик требует функционала в сжатые сроки, а ты не знаешь оптимального решения и делаешь костыль.
>на рабочих проектах оттачивать скиллы
Я так и делаю. Пилю проект, оттачиваю скилл. Потом проект готов и заказчик денег больше не платит, поэтому весь рефакторинг ты можешь делать разве что бесплатно.
>затем через пару лет перекатится на норм язык
На какой такой "норм язык"? Я потому и перекатываюсь со стека на стек, чтобы узнать какой стек наиболее эффективен и удобен в разработке, а не читать про хаскель на двачах.
но тебе не платят много на пхп? вангую что ты макака, для которой учить норм язык ТЯЖЕЛО, и ты занимаешься аутотренингом итт
Цель переката на другой язык – получать удовольствие от программирования, прежде всего. Если я его не получаю, то мне похуй сколько платят.
а вот и ребёнок пожаловал
я спрашиваю конкретно о тебе
как я могу спросить о тебе не переходя на твою личность?
не используй то чем пользоваться не умеешь
>мне похуй сколько платят
то есть у тебя выбор - на яве писать за 40к или на пхп за 20, и тебе будет похуй?
сам понял что написал?
https://ru.wikipedia.org/wiki/Ad_hominem#.D0.9F.D0.B5.D1.80.D0.B5.D1.85.D0.BE.D0.B4_.D0.BD.D0.B0_.D0.BB.D0.B8.D1.87.D0.BD.D0.BE.D1.81.D1.82.D0.B8
>Оскорбительный ad hominem, называемый также «переходом на личности», часто содержит оскорбление или принижение оппонента. В общем случае он состоит в указании на факты, характеризующие самого оппонента, но не имеющие отношения к его аргументации.
>вангую что ты макака
Я то как раз пользуюсь по назначению.
Мне не предложат писать на яве за 40к, если все предыдущее время я писал на пхп.
Но если я начал писать на пхп за 30к, потом понял что мне он не нравится и тут предложили яву (которая мне, предположим, сильно нравится) за 20к – перекачусь на нее.
Если разброс зарплат существеннее – 20к и 60к, то я останусь на пхп, буду делать ежедневный минимум, а остальное время писать свои проекты на любимом языке и съебу как только предложат не 20к, а хотя бы 35.
>не имеющие отношения к его аргументации
сам себя оспорил, красавчик
где твоя аргументация? Ок и Ясно?
Я тебе пояснил свою точку зрения, а потом спросил конкретно о тебе. Не было
никакой дискуссии у нас, а без неё переход на личности невозможен.
не будь ребёнком, признай что ты обосрался
>Argumentum ad hominem — это демагогический приём в котором аргументы оппонента дискредитируются посредством дискредитации оппонента, нежели его аргументы. Просто присутствие негативного комментария о персоналии оппонента не говорит о том что это argumentum ad hominem: только при использовании этого оскорбления для опровержения/дискредитации аргументов оппонента. возможно говорить о демагогическом приёме, иначе говорить о демагогии преждевременно
а теперь можешь укатываться
А я никакой аргументации и не приводил. Я задал вопрос, получил ответ и все. Если ты решил что я с тобой спорю, то это только твоя проблема. Тут ты и начал почему-то переходить на личности. Для того чтобы задать мне вопрос о конкретно моей ситуации, делать это совершенно не обязательно. Такие дела.
>А я никакой аргументации и не приводил.
>Тут ты и начал почему-то переходить на личности.
>Не было никакой дискуссии у нас, а без неё переход на личности невозможен.
упрямый ребёнок
>а потом спросил конкретно о тебе
>ты макака, для которой учить норм язык ТЯЖЕЛО
"спросил конкретно о тебе" это "тебе тяжело учить новый язык? много ли тебе платят за пхп?", а не "ты макака".
>упрямый ребёнок
Мелкобуквенный наркоман опять переходит на личности и занимается софистикой.
ты понял что густейше обосрался и теперь нарочно используешь это неправльно с целью затролить меня? лолнет, уёбывай
Да это вообще другой анон. Нас тут сейчас двое с тобой разговаривает и ты путаешь уже не в первый раз.
да, я
я нашёл охуенный плагин, и даже этот готовый плагин внедрять в существующий модуль админки мне придётся пару дней
но тебе естественно лучше меня видна сложность того что я буду делать
по правилам хорошего тона встревающему в дискуссию нужно подписываться мимопроходилом
почему ты так не сделал?
Забавно что именно ты тут кукарекаешь про пхп-макак и говнокод, разработчиков которые оставляют говнопроект и все страдают.
Ведь именно ты уже целый год лепишь какое-то говно на самодельном! фреймворке, в который внедрить два простых круд действия занимает два дня.
Ты ведь понимаешь, что когда придет новый человек твое говно разгребать, он не будет пердолиться с самописным фреймворком, а просто перепишет весь проект на стандартных технологиях?
>два простых круд действия
>просто перепишет
просто-мэн спешит на помощь
>но тебе естественно лучше меня видна сложность того что я буду делать
и да, ты забыл написать что он ПРОСТО перепишет за неделю, не больше
Читай оп-пост
Не хочу.
я разбиваю свой рабочий проект на миникуски и скидываю итт
каждый кусок - на 4 часа работы
за него плачу 200р.
итого у вас есть возможность применить свои навыки и немного заработать
дана таблица уровня шкаф - ящик - носок
много шкафов, в каждом по 3 ящика
и много носков
задача - дать мне жс плагин такой, чтобы можно было перемещать носки между ящиками, создавать, удалять,править носки
это должно быть на одной странице, при любом действии посылается аякс запрос
мне нужен только фронтенд со всеми фичаи перетаскивания, добавления, удаления, правки
вопрос по теме треда: оп, допустим у меня есть класс хелперов, мелких полезных методов
как мне их включать в классы? через конструктор? но это же нарушит инкапсуляцию или абстракцию
что делать в этом случае?
я не понял
ты споришь с тем что пхп-макак заставляют делать всё от вёрстки до ублажения ануса менеджера? или в чём проблема? ты на пхп пишешь? только не говори что ты чистый бэкэндщик, таких 1 на 1000 обезьян
Я пока никто, будущая макака, откуда мне знать, чем на самом деле вы там занимаетесь?
отвечая на твой вопрос - пхп - самое дно, даже жс круче чем пхп
поэтому можно быть чистым жс програмистом, жс для серверов есть
алсо, беги из пхп
занимайся чем угодно другим, хоть перл, хоть питон, хоть ява, только не пхп
Почему? Платят то больше и освоить легче. Мне похуй на язык, я не какой-нибудь пидрила-эстет.
>Платят то больше
мне платят 18к за год опыта
но ты конечно меня не будешь слушать, ты послушаешь илиту которой платят 50к за 4ч работы в день, и будешь думать что и тебе столько платить будут
Нет-нет, ты обещал разбить проект на куски и скинуть их ITT, а не "найдите мне плагин который сделает все вместо меня".
> сли я пише $app->someObj, то ругается слим на то, что это неопределенная переменная
Ты изучал область видимости переменных? Изучи: http://php.net/manual/ru/language.variables.scope.php (согласен, не очень понятно написано)
Суть в том, что переменные внутри функций (метод тоже функция) и снаружи изолированы. Изнутри функции ты не видишь внешние, глобальные переменные, а снаружи — внутренние, локальные. Это специально сделано ради повышения качества кода.
Если ты в класее используешь какой-то объект (например соединение с БД), уместнее всего передать его через конструктор.
> Если пишу \$app->someObj, то ругается php.
Объясни, что по твоему должен делать бекслеш?
Бекслеш используется в неймспейсах, это верно:
\some\namespace\Class
Но он используется чтобы показать в каком неймспейсе находится класс или функция или константа. У переменных нет неймспейсов.
>за год опыта
Ну пиздец, ходит тут рассказывает охуительные истории весь тред, а оказывается у него просто совершенно нет опыта, но есть здоровенное ЧСВ, которое блокирует все попытки воспринимать информацию.
> скажи, стоит ли мне прямо в лицо, стоит ли мне продолжать или я совсем даун головы?
Если ты интуитивно чувствуешь что твой код не очень хороший, может лучше спрашивать, что в нем не так? Я думаю, что если там и есть ошибки то не от того что ты даун, а от того что такой код был в статьях или уроках по которым ты учился. А они могли например устареть или были написаны не очень разбирающимся человеком.
Да и не везде требуется хороший код. Если ты хочешь быть профессиональным разработчиком в дальнейшем и делать серьезные приложения то, да, надо исправлять ошибки и учиться писать правильно.
Если же ты для себя набросал скриптик на 30 строчек и никому не придется его читать, то в принципе качество кода не очень важно, главное чтобы работало.
Пока это уровень «набросать скриптик для себя». Попозже напишу список замечаний.
Да никакого хитрого плана уже нет. Хотел посмотреть на твой код, но теперь все ясно и без него.
сука идиот нахуй
>я разбиваю свой рабочий проект на миникуски и скидываю итт
те части, которые предстоит сделать, идиот ебаный
и заплачу анону который сделает
такие миниуроки уровня опа
нахуя готовый то скидывать?
Есть разница, написать скриптик для себя или писать код большого приложения в команде. В первом случае качество кода не так важно, так как страдать от него будешь только ты сам.
И что значит «пхп-стайл»? На Node.JS, Ruby, Python, bash, Си/Си++ (о, там вообще можно развернуться) нельзя набыдлокодить скриптик? да легко. Да я уверен, даже на Хаскелле можно набыдлокодить при желании, там есть какая-то закорючка чтобы писать императивный код.
Ну и если человек умеет писать хоть как-то и у него есть желание, он может переучиться на нормальный код. Олимпиадников же переучивают как-то. Быдлокодер — это не тот, кто не умеет писать нормально, а тот кто переучиваться не хочет.
> пхп-программистов считают дном
авторитетные эксперты из /pr/ачечной
>>403373
Книга хорошая, но надо иметь определенный опыт чтобы ее понимать.Челочек, никогда не писавший код длинее 100 строк скорее всего не поймет ее.
>>403393
Если человек изучал принципы ООП, и всякие правила типа «не пиши длинных простыней и сильновложенных ифов», у него обычно сам собой получается более-менее нормальный код.
Есть и противоположные примеры: неопытные (или не понявшие ООП) программисты боятся простых решений и начинают городить лишние абстракции, фабрики, адаптеры, сам такое видел.
> лучше он от этого практически не станет – в силу того что у тебя нет нужного опыта и косяков ты не заметишь.
Верно. Но не думай, что надо быть каким-то гением чтобы научиться правильно писать. Если ты изучаешь ООП, современные фреймворки, заглядываешь иногда в их код, и сам начинаешь писать в таком стиле, получается вполне нормально.
> потому что это самый распространенный и дешевый язык в вебе.
Дешевый он только если ты нанимаешь низкоквалифицированных разработчиков. Да, они есть, люди берут какую-нибудь некачественную книгу и считают себя профессионалами. Может это и не так плохо, лучше какие-то деньги зарабатывать чем никакие.
Ну а «считают дном» это вообще очень субъективное мнение. Почему тогда википедия, вконтакте и фейсбук выбрали этот язык, а не хаскелл какой-нибудь? Потому что фантазии студентиков-математиков, восхищающихся сложными системами типов, и реальность расходятся.
>Почему
потому что тогда ниша пхп не выделялась так ярко
вконтакте и фейсбук перекатываются на какой-то свой язык, форкнутый из пхп
доставь пример крупного проекта, который написан на пхп НЕДАВНО, а не лет 5 назад? нет такого, с появлением новых языков на пхп никто писать не будет
вот в этом вся суть пхп
>и считают себя профессионалами
как понять что я не низкоквалифицированный? мне печёт от 18к
походить по собеседованиям после работы? люди правда так делают? не увольняясь?
> когда ты только начинаешь писать говно – ты еще не знаешь что это говно
Среднестатистическому веб проекту не нужно гениальных архитектур. Берешь нормальный MVC-фреймворк (Симфони 2, Юи 2) и пишешь нормальный MVC код соблюдая правила типа SOLID, тонкие контроллеры и прочее, о чем полно статей на Хабре. Для всяких дополнительных вещей, обычно есть готовые библиотеки. Ты наверно велосипеды пишешь, а потом удивляешься что получается не очень.
Я не думаю, что дело в языке. Ты ведь и на Питоне, и на Руби так же писать будешь. А уж если за Node.JS возьмешься, там вообще простор неограниченный.
>>403449
50 р/час = $1 / час. Такие деньги даже индусам не предлагают. Аноны, не соглашайтесь. Лучше попросите у меня бесплатное задание и получите советы по улучшению кода. Умение писать качественный код принесет вам гораздо больше.
>Среднестатистическому веб проекту не нужно гениальных архитектур
я не понимаю о чём ты
что это за проект которому достаточно 100 методов в модели?
блог Василия?
приведи проект среднестатистического пхп-проекта по твоему
может я и правда хуетой занимаюсь
>Такие деньги даже индусам не предлагают
но они и есть индусы
они поучатся писать код, выложат код сюда, ты посмотришь, я заплачу им.
в чём проблема? почему ты против?
2 доллара в час платят на одеске индусами пакистанцам. Лучше научись нормально программировать и меняй работу.
Алсо, в ДС платят больше чем 300 если ты не совсем джуниор.
>>403467
Есть паттерн UtilityClass. Это когда ты делаешь класс из статических методов. Для надежности можно еще сделать конструктор приватным (чтобы не создавали объекты).
Пример:
class StringUtil {
// Обрезает строку до указанного числа символов
public static function shorten($str, $length) {
....
}
Но он применим именно к таким случаям, когда есть простая функция для работы со строками, массивами, и тд. Если у тебя код, работающий с сущностями (например, удалитьЗаминусованныеКомментарии(пост) ) то естественно он должен быть где-то в сервисах, мапперах и подобных классах, то есть быть частью модели.
Если тебе надо работать с сетью (скачать файл, проверить наличие файла по ссылке), стоит сделать отдельный не статический класс.
>стоит сделать отдельный не статический класс
получается что класс становится неработоспособным без этого метода
как глобальная переменная вне метода
разве это согласуется с ооп?
>не думай, что надо быть каким-то гением чтобы научиться правильно писать
Гением надо быть тем больше, чем сложнее проект.
>Дешевый он только если ты нанимаешь низкоквалифицированных разработчиков
Где их и сосредоточено максимальное количество, по сравнению с другими языками.
>Ну а «считают дном» это вообще очень субъективное мнение
Но ведь считают. Есть такое распространенное мнение.
Это не уроки.
Уроком это будет если ты например подробно опишешь задачу. Опишешь в общих чертах как ее принято решать. Дашь список библиотек для выбора. Потом проверишь код, укажешь на ошибки, если видишь что человек что-то не понимает, дашь ссылку на теорию или напишешь пасту (так как нормальных ссылок нет).
Естественно для урока нельзя давать примеры некачественного кода и велосипеды.
И если ты посчитаешь, сколько на это надо времени, то окажется что даже если задачу решат за бесплатно, это все равно невыгодно.
ну ладно, не уроки
но если анон захочет - то почему нет? почему ты так категорично пишешь НЕ ДЕЛАЙТЕ?
Может потому что ты, мразь, пытаешься нажиться на бедных анончиках?
делают.
http://habrahabr.ru/post/184030/
http://habrahabr.ru/post/183674/
В Москве или Спб (ну и в столицах других стран я думаю тоже), в Калифорнии большой выбор вакансий, появляются новые проекты, всем нужны разработчики потому часто смена работы это лучший способ повысить себе зарплату. Какой смысл повышать сотруднику зарплату просто так? Он что, лучше работать начнет?
Эта тема не раз уже на хабре обсуждалась:
http://geektimes.ru/post/227233/
> Журнал Forbes обратил внимание на интересную тему, о которой не принято говорить: зависимость зарплаты сотрудника от стажа работы в компании. Выясняется, что на максимальную зарплату могут рассчитывать вовсе не лояльные сотрудники, а совсем наоборот — те, кто часто меняет работу.
Стоит правда помнить, что работодатель тоже не дурак. Из всех пришедших на собеседование он выберет тех, кто лучше. Если там будут люди лучше тебя и они немного попросят, ты в пролете.
Потому если ты считаешь что стоишь больше ты можешь таким образом себя проверить. Работодатель всегда заинтересован чтобы платить тебе как можно меньше. И только когда например ему надо срочно набрать N новых человек, или нужно найти профессионала, а никто не идет, он может скрепя сердце (скрипя сердцем? как правильно?) предложить больше. И новичок может получать больше того кто уже 3 года работает.
В общем, хочешь жить, умей вертеться.
>себя проверить
>походить по собеседованиям после работы? люди правда так делают? не увольняясь?
А я например считаю дном не php, а использование технологий только потому что при них написал какой-нибудь клоун в блоге вместо того, чтобы думать головой. Кофескрипт, HAML, большие приложения на Node.js, каждый второй плагин jquery, использовать ангулар где ни попадя - это все то еще дно, на котором быдлокодят не хуже чем на PHP, но при этом быдлокодерами себя почему-то не считают.
Или например люди используют LESS, grunt и 20 плагинов к нему но при этом не разбираются в особенностях позиционирования в CSS. Те же быдловерстальщики, только с грантом.
>при этом не разбираются в особенностях позиционирования в CSS
>люди пишут на пхп, при этом не разбираясь в низкоуровневом программировании
тебе не кажется что это одно и то же
эти инструменты и нужны для того чтобы было легче писать, не вникая глубоко
>я сам бы за 4 часа это не успел нормально сделать
мне один траль тут рассказывал выше что это можно сделать за 3 запроса
это так сложно?
>потому что при них написал какой-нибудь клоун в блоге вместо того, чтобы думать головой
Думать головой может человек, который уже знаком с этой технологией и может сравнить, чем она лучше/хуже php для проекта.
>при этом быдлокодерами себя почему-то не считают
Да чо ж не считают, считают как и все остальные.
А grunt/gulp это сейчас стандарт в веб-разработке (про javascript mvc пока не скажу, но уже скоро) – он просто автоматизирует твои задачи и никак не мешает проекту.
Про три запроса тут никто тебе не говорил. А я говорил про 5 часов – и это реальный срок для такой задачи при условии использования стандартного rest фреймворка.
Нужно верстать страницу, подключать и писать код для драг н дропа. писать код бекенда, тестировать, исправлять замеченные недостатки. Я не представляю как это за 4 часа сделать. Минимум 6-10 чтобы было нормально, при условии что у тебя уже есть нормальный фреймворк например. Если его нет то это лишние затраты, сам понимаешь.
Для неоптыного анона, который должен все изучать по ходу дела, это вообще будет часов 40-60 (то есть 2 недели).
вообще я же писал бэкенд не нужен
просто написать скрипты на драгэндроп и добавление\удаление и посылать аякс запросы
как раз 4 часа
у grunt абсолютно невменяемый способ настройки. Ты можешь написать gruntfile не заглядывая в интернет? По мне так это уродец, любой bash или php скрипт который я писал для аналогичных целей, меньше, проще и понятнее. «Стандартом» он мог стать только от безвыходности.
Инкрементального обновления (например прогонять через препроцесор только изменившиеся файлы) нет. В том же make которому 30 лет — есть (правда, у него синтаксис тоже так себе).
У нормального инструмента должен быть нормальный конфиг, а не кусок быдлокода на JS c кучей скобок, и нормальный набор опций командной строки.
Спрашивают: ок, когда на работу готовы выйти? Я говорю, я работаю над другим проектом, надо все нормально доделать и сдать, только через месяц. Говорят: ок, хорошо, выходите через месяц.
наоборот, ты произведешь впечатление ответственного человека, а не такого который все бросит и убежит (хотя я понимая что ты не такой).
>>403531
Сделал бы уже, раз 4 часа. Ты тут постов нафлудил наверно на 100 строчек уже.
Да я понимаю, что она не моя функция не видит $app. Я не знаю, как это решить.
Бтв, решил добавлением в класс fileMapper поля app, а в конструкторе написал $app = \Slim\Slim::getInstance(); Это же ничего страшного, да?
Сейчас начну дальше делать, но хотелось бы узнать, верно ли пофиксил предыдущие ошибки.
Это отстойно. Вот у меня https://gist.github.com/codedokode/e1d31a31b37d5f635057 написано что надо передавать зависимости в конструктор.
Если тебе в классе A нужен класс B то пиши
class A
{
public function _ _ construct(B $b) {
....
}
Ой, тут какой-то бред. Нвм, сделал что-то.
>403538
>я проверю но часов в 11-12
Так будет даже лучше.
Да мне в общем похуй уродец он или нет, из вменяемых альтернатив есть только gulp, но под него плагинов не так много пока что.
Пока ты будешь писать свои make/bash скрипты под каждую мелочь, я просто накачаю плагинов и у меня будет работать jslint, всякие uglify и контакенаторы, будут автоматически запускаться тесты и обновляться страница при сохранении.
Вообще хочу угореть по хардкору всяким веб-погромированием. Ну чтобы там БД, сайты, движки сайтов и все такое.
Нужен пхп, js, сам java, что еще?
Начинать хочу с пхп. Оцените мои шансы на успех.
Просто использовать их буду как хобби, т.к. специальность совсем другая
Но чому так?
>У нормального инструмента должен быть нормальный конфиг, а не кусок быдлокода на JS c кучей скобок, и нормальный набор опций командной строки
Да и вообще, если ты такой охуенный – выкладывай свои башепхп скрипты на гитхаб и пусть люди пользуются нормальным инструментом, раз грант такое говно.
>угореть по хардкору
>использовать их буду как хобби, т.к. специальность совсем другая
/0
Начни с прочтения ОП-поста и решения задачек. Ты определенно туда зашел.
Накидал вот код по подсчету слов в тексте.
http://ideone.com/oTOX0e
интересует критика опытных ребят. Например можно ли такое запилить на сайт и скармливать ему книги и дирные копипасты через форму? Или в таком случае нужен совсем другой подход?
слишком простое задание чтобы о чём-то рассуждать
можно конечно в стиле опа доебаться до $words = $words[0]; , до слов латинского алфавита, до каких-то исключительных случаев которые встретятся раз в жизнь
ну хуй знает
Не скажи, мой файловый обменник вон проверяет же.
Если для тебя это слишком простое то просто скажи збс все сделал или нет? Ты бы как подобное написал? Можешь ясен хуй не писать, а просто в двух словах описать алгоритм.
http://sqlfiddle.com/#!2/c14494/9
Насколько я понял, вроде так. хотя наверно опять ни хрена не понял(
раз тебе задачи даёт оп, пусть он и проверяет
я надеюсь что ты понял что я не оп.
во первых, я бы делал по-другому
я бы ориентировался по пробелам. всё-таки пробел - это основной и единственный разделитель слов
в твоём варианте есть баг\фича:
оп_хуй, оп>хуй и т.д. считаются за 2 слова. мне кажется это неправильно, пусть даже таких знаков в слове быть не может. мы же парсим не только книжный текст, верно? если мы будем парсить документацию, где переменные вида $op_hui - то оно разделится на 2 слова
но если править твой вариант - вот как бы я сделал: http://ideone.com/K4nP3y (я очень люблю двачесленг, мы же на дваче в конце концов, верно?)
что я изменил:
-убрал лишние инициализации
-переименовал переменные так чтобы они не затирали друг друга
$words = $words[0]; - хуета
$words = $pregResult[0]; - норм
-сменил heredoc на nowdoc, теперь я могу парсить переменные вида $mamkuEbal
-добавил определение английских слов
-добавил проверку входящих данных
-вынес вывод из функции. там не должно быть вывода. функция что делает? countWords - считает слова. почему она выводит их?
-попробуй PHP_EOL, базарю, ещё захочешь
вообще всё зависит от цели использования. тебе не нужно надрачивать задачу до блеска. тебе нужно чтобы она работала. иначе ты будешь тратить на каждую задачу больше времени, и половина введённых тобой фич никогда не пригодится. заметь, я не имею ввиду что нужно писать говно. я имею ввиду именно фичи.
если хуйню пишу - оп поправит
- перерывы больше или равные 30 минут между фильмами, выводятся по уменьшению длительности перерыва
ОП, глянь какое сложное заклинание я написал. Что то тут не так :\
http://sqlfiddle.com/#!2/621c43/6
Есть ли способ обойтись без группировки и HAVING?
> А как это делать? через if + return или через if + die() ?
Идея была такая. Ты пишешь:
if ($remains > 0 && ....) {
} elseif ($remains > 0 && ....) {
...
То есть копипастишь условие. Вместо этого можно сдедать
if ($remains == 0) {
return ...;
}
И дальше это условие не проверять.
> Вот пока переделал функцию smallNumbers()
Лучше, но у меня вопрос. А если попробовать разбить этот сложный if на 3 части, так:
если (число заканчивается на 10-19) { добавляем это число и выходим; }
если (в числе есть десятки и оно >= 20) { добавляем число десятков }
если (в числе есть единицы) { добавляем число единиц (+ проверка isFemale) }
Так код не станет проще? Тут получается вроде меньше ифов и как-то проще условия, не? Хотя твой вариант конечно тоже правильный.
> $hundreds = 0; $tens = 0; $ones = 0;
Не пиши в одну строку, пиши в 3 строки (в PHP можно еще писать $a = $b = $c = 0, так как равно вычисляется справа налево, но в учебной задаче так все же не стоит делать).
В остальном, все пока верно.
> А как это делать? через if + return или через if + die() ?
Идея была такая. Ты пишешь:
if ($remains > 0 && ....) {
} elseif ($remains > 0 && ....) {
...
То есть копипастишь условие. Вместо этого можно сдедать
if ($remains == 0) {
return ...;
}
И дальше это условие не проверять.
> Вот пока переделал функцию smallNumbers()
Лучше, но у меня вопрос. А если попробовать разбить этот сложный if на 3 части, так:
если (число заканчивается на 10-19) { добавляем это число и выходим; }
если (в числе есть десятки и оно >= 20) { добавляем число десятков }
если (в числе есть единицы) { добавляем число единиц (+ проверка isFemale) }
Так код не станет проще? Тут получается вроде меньше ифов и как-то проще условия, не? Хотя твой вариант конечно тоже правильный.
> $hundreds = 0; $tens = 0; $ones = 0;
Не пиши в одну строку, пиши в 3 строки (в PHP можно еще писать $a = $b = $c = 0, так как равно вычисляется справа налево, но в учебной задаче так все же не стоит делать).
В остальном, все пока верно.
Насчет заданий, как сказать. С одной стороны у меня самого (по результатам решения их анонами) накопились мысли что можно поменять, с другой стороны, мне кажется, что эти задачи не стоит добавлять.
Так как это задачки на регулярки, массивы и циклы, и любой наверно кто прошел эти главы, сможет их решить.
> 4. Сравнить два текстовых файла и показать, чего нет в первом, что есть во втором — и наоборот.
А вот это могла бы быть неплохая задача, так как она сложная (но боюсь, ее мало кто решит). Тут нужно использовать алгоритмы вроде таких:
http://c2.com/cgi/wiki?DiffAlgorithm
Ну и если тебе надо на практике, то не надо ее решать, надо взять стандартную утилиту diff
https://ru.wikipedia.org/wiki/Diff
Или любую готовую diff-библиотеку. Я помню, несколько лет назад для себя писал какой-то велосипед для этого на основе готового алгоритма.
В наше время diff-алгоритмы используются много где: от поиска измененных строк в коде в git до поиска различий между огромными цепочками ДНК.
В ОС linux diff является стандартной встроенной утилитой.
> А то 1 задание на функции вообще не круто, у меня оно вообще не вызвало понимание как должна функция работать и как их правильно составлять.
Спасибо, это ценное замечание.
>>403349
Я все собирался-собирался да никак не соберусь. Но я написал мини-урок про работу со строками в php c учетом кодировок: https://gist.github.com/codedokode/ff99e357e9860ea169b8
Согласен, тема кодировок важная, как использовать их внутри php, при работе с mysql, как задавать в html.
>>403351
1) он на английском
2) я как-то смотрел тамошний курс по php и он меня не впечатлил. Плюс там много заданий вида «исправить одно слово в коде», которые дают мало пользы (так как ты не пишешь код и не запоминаешь его)
>>403358
Не, ну подсчет слов, я уверен, анон легко решит после моего учебника.
> а к самой идее, методом проб и перебора приходящих в голову вариатнтов, я потратил не один день.
Это наверно потому, что ты не изучал последовательно нужные темы вроде HTTP, HTTP клиенты, JSON, и тд, а сразу берешься за сложное и спотыкаешься из-за этого.
Теперь про ошибки. Ошибок действительно много. То, что касается оформления:
> $theURL
> $end_URL
Надо называть переменные в одном стиле, а не как попало. В php используется $camelCase. Писать слово the не надо так как оно не несет смысла.
Знак «=» надо отбивать пробелами с обоих сторон.
> $arr
Это бессмысленное имя которое ничего не говорит. Вместо to_read, to_write, arr надо было исплоьзовать 1 переменную, описывающую что это за данные, например savedImages.
> substr($rez[5] , 15);
Это самое неправильное место во всей программе. Так делать нельзя, так как ты полагаешься что нужный тебе ответ будет в определенном месте, а это никто не гарантирует. То есть твой код завтра или послежзавтра сломается. Плюс, абсолютно невозможно понять, что именно ты получаешь таким способом. Вот я смотрю на код, и как я догадаюсь, что идет 15-м байтом в ответе сервера?
У функции get_headers есть мануал ( http://php.net/manual/ru/function.get-headers.php ), там описано как заставить функцию разбирать ответ сервера на массив заголовков. Стоит учесть что по стандартам имена заголовков регистронезависимы и ты обязан искать любые варианты напиcания:
Content-Type
CONTENT-TYPE
content-type
(это я привел как пример, я не знаю какой заголовок ты ищешь).
Также, в заголовки может быть доавблено любое число пробелов.
Твоя ошибка в том, что ты не изучил толком протокол HTTP, а также библиотеки и функции для работы с ним, и пытаешься с ним работать.
Ну и удобнее наверно использовать не get_headers, а библиотеку http-клиент типа guzzle или аналогичный.
> Наверное, можно использовать \t$GLOBALS['theURL'], но я не знаю, как это работает
Не нужно. Все, что нужно функции, надо передавать через аргументы. И копипастить 2 раза URL не придется.
> JSON_FORCE_OBJECT)
> $to_read[(count($to_read)-1)]
Не понимаю логики, у тебя явно числовой массив, почему ты его хочешь кодировать в JSON как словарь?
> get_headers
Встречается несколько раз подряд. Почему ты не вынесешь ее отдельно?
HTML-код не надо смешивать с php, а надо выносить отдельно: http://www.phpinfo.su/articles/practice/shablony_v_php.html
> <br />
Не надо ставить слеш в конце тегов в HTML
> <?php echo
Лучше <?=
> echo "<img
Не пиши html-код внутри echo
> Наверное выбросит нотис.
Конечно выбросит. Используй !empty
> if ( $first_picture_date === $second_picture_date) {
>\t}
Тут надо поменять === на !== и убрать else
В общем, я вижу, что ты то ли учился по каким-то сомнительным урокам, либо, что вероятнее, ты пропускал темы и мало решал задач. Если ты хочешь научиться писать нормально, то быстро, к сожалению не получится. Надо прорешать весь мой учебник + решить сложные дополнительные задания на работу с фреймворками.
> а к самой идее, методом проб и перебора приходящих в голову вариатнтов, я потратил не один день.
Это наверно потому, что ты не изучал последовательно нужные темы вроде HTTP, HTTP клиенты, JSON, и тд, а сразу берешься за сложное и спотыкаешься из-за этого.
Теперь про ошибки. Ошибок действительно много. То, что касается оформления:
> $theURL
> $end_URL
Надо называть переменные в одном стиле, а не как попало. В php используется $camelCase. Писать слово the не надо так как оно не несет смысла.
Знак «=» надо отбивать пробелами с обоих сторон.
> $arr
Это бессмысленное имя которое ничего не говорит. Вместо to_read, to_write, arr надо было исплоьзовать 1 переменную, описывающую что это за данные, например savedImages.
> substr($rez[5] , 15);
Это самое неправильное место во всей программе. Так делать нельзя, так как ты полагаешься что нужный тебе ответ будет в определенном месте, а это никто не гарантирует. То есть твой код завтра или послежзавтра сломается. Плюс, абсолютно невозможно понять, что именно ты получаешь таким способом. Вот я смотрю на код, и как я догадаюсь, что идет 15-м байтом в ответе сервера?
У функции get_headers есть мануал ( http://php.net/manual/ru/function.get-headers.php ), там описано как заставить функцию разбирать ответ сервера на массив заголовков. Стоит учесть что по стандартам имена заголовков регистронезависимы и ты обязан искать любые варианты напиcания:
Content-Type
CONTENT-TYPE
content-type
(это я привел как пример, я не знаю какой заголовок ты ищешь).
Также, в заголовки может быть доавблено любое число пробелов.
Твоя ошибка в том, что ты не изучил толком протокол HTTP, а также библиотеки и функции для работы с ним, и пытаешься с ним работать.
Ну и удобнее наверно использовать не get_headers, а библиотеку http-клиент типа guzzle или аналогичный.
> Наверное, можно использовать \t$GLOBALS['theURL'], но я не знаю, как это работает
Не нужно. Все, что нужно функции, надо передавать через аргументы. И копипастить 2 раза URL не придется.
> JSON_FORCE_OBJECT)
> $to_read[(count($to_read)-1)]
Не понимаю логики, у тебя явно числовой массив, почему ты его хочешь кодировать в JSON как словарь?
> get_headers
Встречается несколько раз подряд. Почему ты не вынесешь ее отдельно?
HTML-код не надо смешивать с php, а надо выносить отдельно: http://www.phpinfo.su/articles/practice/shablony_v_php.html
> <br />
Не надо ставить слеш в конце тегов в HTML
> <?php echo
Лучше <?=
> echo "<img
Не пиши html-код внутри echo
> Наверное выбросит нотис.
Конечно выбросит. Используй !empty
> if ( $first_picture_date === $second_picture_date) {
>\t}
Тут надо поменять === на !== и убрать else
В общем, я вижу, что ты то ли учился по каким-то сомнительным урокам, либо, что вероятнее, ты пропускал темы и мало решал задач. Если ты хочешь научиться писать нормально, то быстро, к сожалению не получится. Надо прорешать весь мой учебник + решить сложные дополнительные задания на работу с фреймворками.
Целый тред поехавших долбоебов, смотрите-ка, лол. Просто не могу не посрать здесь. Сиренькнул в ебло ОП-а, окропил толпу нюфагов. Fuck yeah
эпическая пидораха, фу таким быть
Это самый охуенный и полезный тред во всем /pr/. Тут люди учатся программировать, помогают друг другу и общаются без рейджа и пустых оскорблений.
Это поехавший мелкобуквенный наркоман тут воду мутит и те кто ему отвечает я.
Я сейчас полистал книгу (я ее не читал никогда), книга действительно очень годная и умная. Конечно, она не для начинающих, но тому, у кого уже есть опыт, она будет очень полезна.
>>403374
Серия постов «дайджест новостей из мира php» на хабре. Можно узнавать про всякие новые библиотеки: http://habrahabr.ru/company/zfort/
> Можешь объяснить подробнее? Я не понимаю в чем смысл.
File — это объект, представляющий собой загруженный на сервис файл. У него есть обязательный параметр id в конструкторе. Значит, ты не можешь создать объект File, не указав его id, верно?
id генерируются базой данных при вставке записи в таблицу. Значит до вставки информации о файле в таблицу ты не можешь создать объект File.
По моему то серьезный недостаток. Неудобно же.
Конечно ты обходишь этот недостаток, передавая null в качестве id:
> return new File(null, ....
Но это не решение, а обход ошибки в проектировании класса File. Решение — это убрать необязательные параметры из конструктора. Если файл может быть без id (пока он не сохранен в базу), значит id не должно быть в конструкторе.
Если подумать, то у объекта File все поля можно указывать не в момент создания, а позже. Значит, надо сделать либо конструктор без аргументов, либо с необязательным аргументом типа массив:
_ _ construct (array $values = array())
Но мне кажется, решение с пустым конструктором будет чище и «правильнее». То есть создание файл выглядит так:
$file = new File( );
$file->setName($name);
....
А для загрузки из базы, можно сделать метод, который проставляет значения полей из переданного массива.
Кстати, если ты пишешь руками методы get/set, есть способ лучше. Лучше нагугли или создай готовые сниппеты. Если у тебя SublimeText, вот мой сниппет: https://gist.github.com/codedokode/cd2f41c8dcf1237fde4b
Вызывается нажатием gs [tab]
Если другой редактор, то в нем наверно есть своя система сниппетов.
> Можешь объяснить подробнее? Я не понимаю в чем смысл.
File — это объект, представляющий собой загруженный на сервис файл. У него есть обязательный параметр id в конструкторе. Значит, ты не можешь создать объект File, не указав его id, верно?
id генерируются базой данных при вставке записи в таблицу. Значит до вставки информации о файле в таблицу ты не можешь создать объект File.
По моему то серьезный недостаток. Неудобно же.
Конечно ты обходишь этот недостаток, передавая null в качестве id:
> return new File(null, ....
Но это не решение, а обход ошибки в проектировании класса File. Решение — это убрать необязательные параметры из конструктора. Если файл может быть без id (пока он не сохранен в базу), значит id не должно быть в конструкторе.
Если подумать, то у объекта File все поля можно указывать не в момент создания, а позже. Значит, надо сделать либо конструктор без аргументов, либо с необязательным аргументом типа массив:
_ _ construct (array $values = array())
Но мне кажется, решение с пустым конструктором будет чище и «правильнее». То есть создание файл выглядит так:
$file = new File( );
$file->setName($name);
....
А для загрузки из базы, можно сделать метод, который проставляет значения полей из переданного массива.
Кстати, если ты пишешь руками методы get/set, есть способ лучше. Лучше нагугли или создай готовые сниппеты. Если у тебя SublimeText, вот мой сниппет: https://gist.github.com/codedokode/cd2f41c8dcf1237fde4b
Вызывается нажатием gs [tab]
Если другой редактор, то в нем наверно есть своя система сниппетов.
По коду:
В файле composer.json ошибка. Она даже на гитхабе подсвечивается цветом. Попробуй сделай composer validate и увидишь.
create.sql не исправлен
size логично пометить как UNSIGNED
В index.php у тебя 2 одинаковых функции: / и /home/ . Неправильно. Не должно быть чтобы у одной и той же страницы было 2 разных URL. Если тебе надо чтобы работали оба URL, надо в одном из них поставит редирект 301, но по моему так home вообще не нужен.
Теперь про автозагрузчик. Автозагрузчиков в php может быть один или много? Много. Например, сторонняя библиотека может добавить автозагрузчик для загрузки своих классов. Раз так, то твоему автозагрузчику могут попадать запросы на загрузку каких-то классов которых нет в твоем приложении. А он у тебя всегда делает
require_once
и это вызовет ошибку. Ты должен исправить его, чтобы он загружал файл только если он существует, а если нет, ничего не делать — может быть другой автозагрузчик его найдет. Например, у Слима свой автозагрузчик настроен для своих классов.
Исправил? Молодец.
А теперь удаляй этот автозагрузчик, так как в композере есть поддержка нескольких видов автозагрузки: PSR-0, PSR-4 и classmap (это когда в коде никакой логики нет и композер сканирует все файлы, составляя список в каком классе какой файл). Ты используешь, я надеюсь, стандартный подход, раз так то добавь пару опций в composer.json, сделай composer update и получи работающую без написания кода автозагрузку. Как хорошо когда следуешь стандартам!
Мануал: https://getcomposer.org/doc/04-schema.md#autoload (англ)
В чем разница между psr-4 и psr-0? 1) обработка подчеркиваний в именах 2) структура папок.
Кстати, заметь что с композером тебе не надо подключать вручную автозагрузчики для всех внешних библиотек: композер настраивает их сам. Те же, кто не осилил композер (а их много), до сих пор руками копируют архивы и копипастят код подключения нужной библиотеки.
По коду:
В файле composer.json ошибка. Она даже на гитхабе подсвечивается цветом. Попробуй сделай composer validate и увидишь.
create.sql не исправлен
size логично пометить как UNSIGNED
В index.php у тебя 2 одинаковых функции: / и /home/ . Неправильно. Не должно быть чтобы у одной и той же страницы было 2 разных URL. Если тебе надо чтобы работали оба URL, надо в одном из них поставит редирект 301, но по моему так home вообще не нужен.
Теперь про автозагрузчик. Автозагрузчиков в php может быть один или много? Много. Например, сторонняя библиотека может добавить автозагрузчик для загрузки своих классов. Раз так, то твоему автозагрузчику могут попадать запросы на загрузку каких-то классов которых нет в твоем приложении. А он у тебя всегда делает
require_once
и это вызовет ошибку. Ты должен исправить его, чтобы он загружал файл только если он существует, а если нет, ничего не делать — может быть другой автозагрузчик его найдет. Например, у Слима свой автозагрузчик настроен для своих классов.
Исправил? Молодец.
А теперь удаляй этот автозагрузчик, так как в композере есть поддержка нескольких видов автозагрузки: PSR-0, PSR-4 и classmap (это когда в коде никакой логики нет и композер сканирует все файлы, составляя список в каком классе какой файл). Ты используешь, я надеюсь, стандартный подход, раз так то добавь пару опций в composer.json, сделай composer update и получи работающую без написания кода автозагрузку. Как хорошо когда следуешь стандартам!
Мануал: https://getcomposer.org/doc/04-schema.md#autoload (англ)
В чем разница между psr-4 и psr-0? 1) обработка подчеркиваний в именах 2) структура папок.
Кстати, заметь что с композером тебе не надо подключать вручную автозагрузчики для всех внешних библиотек: композер настраивает их сам. Те же, кто не осилил композер (а их много), до сих пор руками копируют архивы и копипастят код подключения нужной библиотеки.
> https://github.com/sqghub/uppu.ru/blob/master/index.php#L44
Это лучше переписать чтобы логика была понятнее:
$data['file'] = ...;
if (!$data['file']) {
$app->notFound( );
}
.... продолжение ...
После удачной загрузки надо редиректить на страницу файла, не надо заставлять жать на ссылку наверно.
> echo "<h1>{
Не пиши html внутри echo. Не пиши echo в шаблоне никогда. Тебе же надоест бекслеши и скобки ставить. Пиши как тут: http://www.phpinfo.su/articles/practice/shablony_v_php.html
Не используй в шаблонах скобки после foreach, используй версию с двоеточием (она лучше читается):http://php.net/manual/ru/control-structures.alternative-syntax.php
После этого исправь все шаблоны.
Не используй br после h1, так как h1 блочный тег. Может тебе задачки из «пути верстальщика» порешать еще стоит?
Ну и h2 нельзя использовать для задания размера шрифта. Это тег обозначает подзаголовок, а ты используешь его как «вывести крупным шрифтом»
Для вывода сообщений в Twitter есть специальные стили: http://getbootstrap.com/components/#alerts
Пролистай документацию по bootsrap (разделы CSS и Components — оба) чтобы представлять что в нем есть. Даже если ты английский не знаешь, картинки и код любой поймет. Это тебе наверняка пригодится.
Есть русский перевод http://mybootstrap.ru/base-css/ но по моему он от 2-й версии бутстрапа.
> https://github.com/sqghub/uppu.ru/blob/master/static/bootstrap/starter-template.css
Это не часть bootstrap. Это что-то левое, не знаю, зачем ты его туда положил. Скачай на всякий случай настоящий бутстрап отсюда: http://getbootstrap.com/ и положи вместо своего.
> $data['file']->getName( )
Надо писать просто $file->getName( ) так как функция render создает переменные на основе переданного массива. Так удобнее же.
> $filePath = "userFiles/{$data['file']->getId( )}/{$data['file']->getName( )}";
Это сложная логика определения пути к файлу. Ей не место в шаблоне.
> $data['file']->getSize( )%1024;
Это надо вынести в метод например в классе Util или еще где-то с понятным именем.
> if (preg_match("/image\/./", $data['file']->getType( ))) {
Это сложная логика определения типа файла, ей не место в шаблоне
> $imageSize = getimagesize($filePath);
То же самое
(алсо пока я писал этот пост ты, пока я не успел запретить, добавил еще кучу кода в шаблон хотя шаблон не для кода а только для вывода данных — для логики есть методы и функции).
Ну и еще, при выводе данных ты рискуешь создать уязвимость XSS. Изучи инструкцию по борьбе с ней: https://gist.github.com/anonymous/52adda0113428b274c64
> https://github.com/sqghub/uppu.ru/blob/master/index.php#L44
Это лучше переписать чтобы логика была понятнее:
$data['file'] = ...;
if (!$data['file']) {
$app->notFound( );
}
.... продолжение ...
После удачной загрузки надо редиректить на страницу файла, не надо заставлять жать на ссылку наверно.
> echo "<h1>{
Не пиши html внутри echo. Не пиши echo в шаблоне никогда. Тебе же надоест бекслеши и скобки ставить. Пиши как тут: http://www.phpinfo.su/articles/practice/shablony_v_php.html
Не используй в шаблонах скобки после foreach, используй версию с двоеточием (она лучше читается):http://php.net/manual/ru/control-structures.alternative-syntax.php
После этого исправь все шаблоны.
Не используй br после h1, так как h1 блочный тег. Может тебе задачки из «пути верстальщика» порешать еще стоит?
Ну и h2 нельзя использовать для задания размера шрифта. Это тег обозначает подзаголовок, а ты используешь его как «вывести крупным шрифтом»
Для вывода сообщений в Twitter есть специальные стили: http://getbootstrap.com/components/#alerts
Пролистай документацию по bootsrap (разделы CSS и Components — оба) чтобы представлять что в нем есть. Даже если ты английский не знаешь, картинки и код любой поймет. Это тебе наверняка пригодится.
Есть русский перевод http://mybootstrap.ru/base-css/ но по моему он от 2-й версии бутстрапа.
> https://github.com/sqghub/uppu.ru/blob/master/static/bootstrap/starter-template.css
Это не часть bootstrap. Это что-то левое, не знаю, зачем ты его туда положил. Скачай на всякий случай настоящий бутстрап отсюда: http://getbootstrap.com/ и положи вместо своего.
> $data['file']->getName( )
Надо писать просто $file->getName( ) так как функция render создает переменные на основе переданного массива. Так удобнее же.
> $filePath = "userFiles/{$data['file']->getId( )}/{$data['file']->getName( )}";
Это сложная логика определения пути к файлу. Ей не место в шаблоне.
> $data['file']->getSize( )%1024;
Это надо вынести в метод например в классе Util или еще где-то с понятным именем.
> if (preg_match("/image\/./", $data['file']->getType( ))) {
Это сложная логика определения типа файла, ей не место в шаблоне
> $imageSize = getimagesize($filePath);
То же самое
(алсо пока я писал этот пост ты, пока я не успел запретить, добавил еще кучу кода в шаблон хотя шаблон не для кода а только для вывода данных — для логики есть методы и функции).
Ну и еще, при выводе данных ты рискуешь создать уязвимость XSS. Изучи инструкцию по борьбе с ней: https://gist.github.com/anonymous/52adda0113428b274c64
>(алсо пока я писал этот пост ты, пока я не успел запретить, добавил еще кучу кода в шаблон хотя шаблон не для кода а только для вывода данных — для логики есть методы и функции).
Это я знаю. Я пока не решил, как это оттуда убрать.
>Ну и еще, при выводе данных ты рискуешь создать уязвимость XSS. Изучи инструкцию по борьбе с ней:
Читал. Пока что только в имени файла это убрал.
>После удачной загрузки надо редиректить на страницу файла, не надо заставлять жать на ссылку наверно.
Просто не знал, как это делается.
>Не используй br после h1, так как h1 блочный тег. Может тебе задачки из «пути верстальщика» порешать еще стоит?
Определенно стоит, но мне верстка совсем скучной выглядит.
>так как функция render создает переменные на основе переданного массива.
А этого я не знал.
https://github.com/sqghub/uppu.ru/blob/master/model/DataBase.php#L5
Это неудобно. Чтобы развернуть твой проект, надо как-то найти эти параметры и править код (представь что например твои коллеги используют другие параметры Бд — что им делать? вписать свои, закоммитить файл и в итоге все перестанет работать у тебя).
Чтобы не было этой проблемы, данные выносят в конфиг config.php. Это может быть файл вида
$config['dbHost'] = '127.0.0.1';
или даже так, используя возможности Слима:
$app->config('dbHost', '127.0.0.1');
Заметь, что это решает проблему «как найти параметры Бд» но не решает проблему «как разработчику переопределить параметры». Для второй проблемы в конце файла конфига мы пишем
$localConfig = _ _ DIR _ _ .'/config.local.php';
Если (этот файл существует) { инклудим его }
И внести config.local.php в gitignore. Таким образом, каждый сможет у себя переопределить настройки БД не трогая репозиторий.
> require_once 'File.php';
Это уже не нужно
> construct($dataBase)
нужен тайп хинт
> https://github.com/sqghub/uppu.ru/blob/master/model/FileMapper.php#L15
Слишком длинный if. Переверни if и избавься от else
> $result['code'] = 1;
Тут надо использовать не цифры, а константы вида FileMapper::ERROR_FILE_NOT_SENT
> $file->setName(htmlspecialchars($file->getName(), ENT_QUOTES));
Это надо делать при выводе а не при хранении в Бд. Представь, что ты захочешь написать команду которая выводит имена файлов в командную строку. Там они будут выводиться в закодированном виде что очевидно плохо.
> public function save(File $file,$dir)
Слишком много кода в одной функции (с учетом того что это учебная задача и мы все делаем правильно)
> $this->dataBase->DBH
В чем смысл класса DataBase если можно сразу передавать PDO?
> FROM `files` WHERE `id`=$id
Не вставляй никогда переменные в запрос — это путь к SQL-инъекциям. Используй плейсхолдеры: http://habrahabr.ru/post/137664/
Удобнее наверно если функция getLast будет возвращать не массив массивов, а массив объектов File? Тогда мы бы могли использовать какие-то полезные методы этого класса (пока их правда все равно нет).
> $query->setFetchMode(\PDO::FETCH_ASSOC);
Это наверно лучше делать только один раз в самом начале.
При загрузке надо проверять код ошибки от PHP как описано тут: http://php.net/manual/ru/features.file-upload.post-method.php Можно не писать сообщения для каждого вида ошибки, а просто одно сообщение на все случаи.
Также, у тебя скорее всего есть уязвимость. Что, если загрузить файл 1.php к тебе на сервер и выполнить через браузер? Он выполнится? Тогда любой школьник тебя легко взломает.
https://github.com/sqghub/uppu.ru/blob/master/model/DataBase.php#L5
Это неудобно. Чтобы развернуть твой проект, надо как-то найти эти параметры и править код (представь что например твои коллеги используют другие параметры Бд — что им делать? вписать свои, закоммитить файл и в итоге все перестанет работать у тебя).
Чтобы не было этой проблемы, данные выносят в конфиг config.php. Это может быть файл вида
$config['dbHost'] = '127.0.0.1';
или даже так, используя возможности Слима:
$app->config('dbHost', '127.0.0.1');
Заметь, что это решает проблему «как найти параметры Бд» но не решает проблему «как разработчику переопределить параметры». Для второй проблемы в конце файла конфига мы пишем
$localConfig = _ _ DIR _ _ .'/config.local.php';
Если (этот файл существует) { инклудим его }
И внести config.local.php в gitignore. Таким образом, каждый сможет у себя переопределить настройки БД не трогая репозиторий.
> require_once 'File.php';
Это уже не нужно
> construct($dataBase)
нужен тайп хинт
> https://github.com/sqghub/uppu.ru/blob/master/model/FileMapper.php#L15
Слишком длинный if. Переверни if и избавься от else
> $result['code'] = 1;
Тут надо использовать не цифры, а константы вида FileMapper::ERROR_FILE_NOT_SENT
> $file->setName(htmlspecialchars($file->getName(), ENT_QUOTES));
Это надо делать при выводе а не при хранении в Бд. Представь, что ты захочешь написать команду которая выводит имена файлов в командную строку. Там они будут выводиться в закодированном виде что очевидно плохо.
> public function save(File $file,$dir)
Слишком много кода в одной функции (с учетом того что это учебная задача и мы все делаем правильно)
> $this->dataBase->DBH
В чем смысл класса DataBase если можно сразу передавать PDO?
> FROM `files` WHERE `id`=$id
Не вставляй никогда переменные в запрос — это путь к SQL-инъекциям. Используй плейсхолдеры: http://habrahabr.ru/post/137664/
Удобнее наверно если функция getLast будет возвращать не массив массивов, а массив объектов File? Тогда мы бы могли использовать какие-то полезные методы этого класса (пока их правда все равно нет).
> $query->setFetchMode(\PDO::FETCH_ASSOC);
Это наверно лучше делать только один раз в самом начале.
При загрузке надо проверять код ошибки от PHP как описано тут: http://php.net/manual/ru/features.file-upload.post-method.php Можно не писать сообщения для каждого вида ошибки, а просто одно сообщение на все случаи.
Также, у тебя скорее всего есть уязвимость. Что, если загрузить файл 1.php к тебе на сервер и выполнить через браузер? Он выполнится? Тогда любой школьник тебя легко взломает.
htmlspecialchars должна стоять в шаблоне так как это экранирование для вывода в HTML, значит она только при выводе в html и должна использоваться. В базе удобнее хранить исходное имя как есть.
> if (!Array.isArray) {
Это незачем делать при каждом вывзове функции. Это надо вынести из нее. Или написать свою функцию isArray
> if (varTmp.isArray) {
Неправильно используешь isArray. Это функция а не свойство массива. Ты протестировал свой код? Не работает же.
> Запилил: http://jsfiddle.net/jnr1ctbb/
> var self = func
Незачем создавать еще переменную, можно использовать func
В остальном верно.
> Задачка №6
После if надо использовать {}, i =0 удобнее поместить в for так как оно к нему относится. Так, сама задача решена хорошо.
>>403430
> Задача №7
После for надо использовать {}, также тут можно передавать в apply сразу arguments без цикла и массива (apply принимает на вход псевдомассив arguments. Псевдомассив так как arguments это не настоящий массив — у него нет методов вроде slice — а просто объект с полями 0, 1, и тд)
В остальном верно
> if (!Array.isArray) {
Это незачем делать при каждом вывзове функции. Это надо вынести из нее. Или написать свою функцию isArray
> if (varTmp.isArray) {
Неправильно используешь isArray. Это функция а не свойство массива. Ты протестировал свой код? Не работает же.
> Запилил: http://jsfiddle.net/jnr1ctbb/
> var self = func
Незачем создавать еще переменную, можно использовать func
В остальном верно.
> Задачка №6
После if надо использовать {}, i =0 удобнее поместить в for так как оно к нему относится. Так, сама задача решена хорошо.
>>403430
> Задача №7
После for надо использовать {}, также тут можно передавать в apply сразу arguments без цикла и массива (apply принимает на вход псевдомассив arguments. Псевдомассив так как arguments это не настоящий массив — у него нет методов вроде slice — а просто объект с полями 0, 1, и тд)
В остальном верно
> Задачка №8
> for (var property in obj)
Слишком сложно. Давай без for
>>403440
Это тред обучения php и web разработке (включая SQL, HTML, JS, CSS).
>>403447
Я обновил задание, поменяв порядок аргументов (почему? потому что так в lodash сделано).
> if (isEven(array))
Надо чтобы работало с любой переданной функцией а ты прописал isEven
>>403480
> у тебя в этой строке c написана
fixed
Задача 10 — верно.
> нет такого, с появлением новых языков на пхп никто писать не будет
Я 5 лет назад думал так же, ничего не изменилось пока. Когда-нибудь изменится, но не сейчас. Изменится, и мы учебник может быть переделаем (хотя я не думаю, что много менять придется — циклы, они и в Питоне циклы).
> написан на пхп НЕДАВНО, а не лет 5 назад?
Это проекты еще могут быть малоизвестны и пока не выстрелили. Как я их найду? А в чем проблема с 5-летними проектами? django, ror 5 лет назад уже были.
Плюс, угадай, на каком стеке работает огромное число веб-студий?
На hh.ru пока по всей России PHP = 2500 вакансий, Python = 1200, haskell = 18
Вообще, я не против того же Питона, он хороший и синтаксис у него лучше чем у PHP (хотя без private свойств по моему плохо, зря они так). И у него есть отличный набор библиотек. И django неплохой фреймворк. Но например виртуальная машина с JIT — HipHop VM для PHP есть, а для Питона (пока) нет.
И Node.JS неплохая (если на ней не писать средние и большие приложения конечно), вокруг нее хорошая инфраструктура.
Но PHP они пока не обогнали.
>>403509
> приведи проект среднестатистического пхп-проекта по твоему
habrahabr.ru
avito.ru
hh.ru
badoo
Пока они не стали highload, там ничего сложного не было нужно (на хабре подозреваю и сейчас ничего сложного нет). Если ты считаешь, что там нужны какие-то нестандартные подходы, напиши для чего.
> нет такого, с появлением новых языков на пхп никто писать не будет
Я 5 лет назад думал так же, ничего не изменилось пока. Когда-нибудь изменится, но не сейчас. Изменится, и мы учебник может быть переделаем (хотя я не думаю, что много менять придется — циклы, они и в Питоне циклы).
> написан на пхп НЕДАВНО, а не лет 5 назад?
Это проекты еще могут быть малоизвестны и пока не выстрелили. Как я их найду? А в чем проблема с 5-летними проектами? django, ror 5 лет назад уже были.
Плюс, угадай, на каком стеке работает огромное число веб-студий?
На hh.ru пока по всей России PHP = 2500 вакансий, Python = 1200, haskell = 18
Вообще, я не против того же Питона, он хороший и синтаксис у него лучше чем у PHP (хотя без private свойств по моему плохо, зря они так). И у него есть отличный набор библиотек. И django неплохой фреймворк. Но например виртуальная машина с JIT — HipHop VM для PHP есть, а для Питона (пока) нет.
И Node.JS неплохая (если на ней не писать средние и большие приложения конечно), вокруг нее хорошая инфраструктура.
Но PHP они пока не обогнали.
>>403509
> приведи проект среднестатистического пхп-проекта по твоему
habrahabr.ru
avito.ru
hh.ru
badoo
Пока они не стали highload, там ничего сложного не было нужно (на хабре подозреваю и сейчас ничего сложного нет). Если ты считаешь, что там нужны какие-то нестандартные подходы, напиши для чего.
> получается что класс становится неработоспособным без этого метода
как глобальная переменная вне метода
Получается что класс зависит от другого (класса, а не метода) и это нормально. Допустим есть класс, скачивающий все картинки в папку. Естественно работу с http (скачивание файла) надо выносить в отдельный класс HTTPClient. Вот как выглядит код:
$client = new HttpClient( );
// если надо настраиваем клиент, задаем опции типа таймаута и тд
$downloader = new ImagesDownloader($client);
$downloader->downloadImages('http://exmple.com/');
Разделение на 2 класса дает нам:
— разделение ответственности: каждый класс занимается своим делом
— повторное использование: http клиента можно использовать в других местах кода
— гибкость: мы можем настроить клиент как захотим (например задать таймаут и реакцию на ошибки, прокси сервер)
— тестирование: мы можем для тестов вместо клиента подсунуть класс-заглушку не поменяв ни строчки кода
Это и есть правильное использование ООП.
LESS никак не избавляет от необходимости знать особенности позиционирования inline блоков. Вообще-то LESS это лишь инструмент для написания кода, он голову не заменяет, а знать особенности позиционирования — это необходимое требование для верстки.
LESS не заменяет знание CSS никак.
Алсо, LESS по моему провоцирует на быдлокод, я видел уже несколько раз такое:
body {
.header {
div {
margin: 4px;
li {
margin: 3px;
a {
color: red;
....
думаю почему это быдлокод, объяснять не надо?
>>403528
Там еще редактирование нескольких видов сущностей надо сделать (а там внезапно может понадобиться валидация например). Не только перетаскивание. И всю верстку тоже делаешь сам, и интегрируешь в аноновский велосипед, как я понял.
>>403530
Это был я вообще-то. >>403523\t
>>403536
Что ты скорее всего не особо ответственный и думал бы как скорее на более высокооплачиваемую работу перейти.
>>403547
> я просто накачаю плагинов и у меня будет работать jslint, всякие uglify и контакенаторы, будут автоматически запускаться тесты
Время надо на изучение, скачивание поиск и настройку. сопоставимое или превышающее bash скрипт на 5 строчек. Если у тебя не мега проект. Одна конкатенация чего стоит, надо чтобы в dev режиме не склеивалось и не сжималось, а в production сжималось но без вырезания переводов строк (зачем, догадайся сам).
> и обновляться страница при сохранении.
Это дело вкуса, я такое не люблю так как оно постоянно грузит процессор, а я чуть ли не после каждой строчки ctrl + S привык жать.
>>403548
В этой теме не обсуждается организация «дудоса». Это в другой раздел.
Сайты на php писать можно.
> сам java, что еще?
Ява не нужен. Яваскрипт может пригодиться.
LESS никак не избавляет от необходимости знать особенности позиционирования inline блоков. Вообще-то LESS это лишь инструмент для написания кода, он голову не заменяет, а знать особенности позиционирования — это необходимое требование для верстки.
LESS не заменяет знание CSS никак.
Алсо, LESS по моему провоцирует на быдлокод, я видел уже несколько раз такое:
body {
.header {
div {
margin: 4px;
li {
margin: 3px;
a {
color: red;
....
думаю почему это быдлокод, объяснять не надо?
>>403528
Там еще редактирование нескольких видов сущностей надо сделать (а там внезапно может понадобиться валидация например). Не только перетаскивание. И всю верстку тоже делаешь сам, и интегрируешь в аноновский велосипед, как я понял.
>>403530
Это был я вообще-то. >>403523\t
>>403536
Что ты скорее всего не особо ответственный и думал бы как скорее на более высокооплачиваемую работу перейти.
>>403547
> я просто накачаю плагинов и у меня будет работать jslint, всякие uglify и контакенаторы, будут автоматически запускаться тесты
Время надо на изучение, скачивание поиск и настройку. сопоставимое или превышающее bash скрипт на 5 строчек. Если у тебя не мега проект. Одна конкатенация чего стоит, надо чтобы в dev режиме не склеивалось и не сжималось, а в production сжималось но без вырезания переводов строк (зачем, догадайся сам).
> и обновляться страница при сохранении.
Это дело вкуса, я такое не люблю так как оно постоянно грузит процессор, а я чуть ли не после каждой строчки ctrl + S привык жать.
>>403548
В этой теме не обсуждается организация «дудоса». Это в другой раздел.
Сайты на php писать можно.
> сам java, что еще?
Ява не нужен. Яваскрипт может пригодиться.
> foreach($words as $word) {
array_count_values
> "/[а-яё\-]+/ui";
В юникоде каждый символ имеет пометки, является ли он буквой, цифрой итд. И есть возможность искать по этому условию: http://php.net/manual/ru/regexp.reference.unicode.php
А как иначе? Добавив a-z ты все равно несможешь искать слова где есть буквы с точками и закорючками вроде ́a
В остальном норм
>>403569
> конечно в стиле опа доебаться до $words = $words[0];
Ты прав, это плохо так писать
> до слов латинского алфавита,
Ты считаешь плохо что я рассказал про свойства символов?
>>403573
я читаю ((
>>403605
> всё-таки пробел - это основной и единственный
Нет. Слова могут быть разделены запятой без пробелов. Или есть брать код
this.variable.field = 1
тут явно 3 слова: this, variable, field
Про подчеркивание здравая мысль.
> либо фолс если что-то пошло не так
Не может быть такого. А если и может то удобнее использовать исключения, так как с false твоя программа обрастает ненужными ифами, можешь почитать: https://gist.github.com/codedokode/65d43ca5ac95c762bc1a
С исключениями if становится не нужен.
> empty($text)
Непонятно почему это ошибка а не текст из 0 слов
> $wordRegexp
лучше использовать свойства юникодных символов и array_count_values
> foreach($words as $word) {
array_count_values
> "/[а-яё\-]+/ui";
В юникоде каждый символ имеет пометки, является ли он буквой, цифрой итд. И есть возможность искать по этому условию: http://php.net/manual/ru/regexp.reference.unicode.php
А как иначе? Добавив a-z ты все равно несможешь искать слова где есть буквы с точками и закорючками вроде ́a
В остальном норм
>>403569
> конечно в стиле опа доебаться до $words = $words[0];
Ты прав, это плохо так писать
> до слов латинского алфавита,
Ты считаешь плохо что я рассказал про свойства символов?
>>403573
я читаю ((
>>403605
> всё-таки пробел - это основной и единственный
Нет. Слова могут быть разделены запятой без пробелов. Или есть брать код
this.variable.field = 1
тут явно 3 слова: this, variable, field
Про подчеркивание здравая мысль.
> либо фолс если что-то пошло не так
Не может быть такого. А если и может то удобнее использовать исключения, так как с false твоя программа обрастает ненужными ифами, можешь почитать: https://gist.github.com/codedokode/65d43ca5ac95c762bc1a
С исключениями if становится не нужен.
> empty($text)
Непонятно почему это ошибка а не текст из 0 слов
> $wordRegexp
лучше использовать свойства юникодных символов и array_count_values
> добавил определение английских слов
А французских, немецких? С их странной буквой ß ?
> вынес вывод из функции.
Правильно
> попробуй PHP_EOL
Я советую просто \n. Смотри, тут такая история:
Много лет назад был Мак с разделителем строк \r и unix c \n. Когда Билл Гейтс делал MS DOS, он решил обеспечить совместимость и сделал \r\n (чтобы переносы отображались везде). От этого конечно появилось больше проблем чем выгоды.
В наше время мак перешел на \n (андроид, айфон — тоже \n) и кроме Windows все используют \n. При этом \n работает и под виндой, просто в блокноте он не вызывает переноса строки. Но в виндовой консоли например \n переводит строку.
Мое мнение — ради какого-то виндового блокнота напрягаться не стоит и стоит просто всегда использовать \n.
Если я разбиваю текст на строки, я просто разбиваю по \n и удаляю \r через trim. И работает везде.
Ну и приложение надежнее так как на любой платформе генерирует файлы одного формата.
Естественно это не касается сетевых протоколов вроде http где комбинация \r\n прописана стандартом.
Кстати точно такая же история с разделителем директорий. На древних маках было двоеточие, в юниксе прямой слеш /, а когда Билл Гейтс делал ДОС, слеш использовался в одной программе как указатель опций — потому он сделал разделителем бекслеш.
В наше время все ОС — mac, linux, windows — понимают прямой слеш как разделитель (если ты используешь функции тип fopen, file_get_contents).
Потому проще использовать / везде чем мучаться с длинным DIRECTORY_SEPARATOR.
Стоит помнить что функции типа realpath или константы _ _ FILE _ _ под виндой вернут тебе имя с бекслешами.
>>403605
Пасибо за такой полный ответ бро. Вообще ты прав и тут смотря под какие цели делать, я делал под книжный русский текст и имхо пробелы это больше гемора. Сначала нужно затерать кучу всевозможной пунктуации, что бы не было дублирущихся слов и мутантов типа:
хуй - встретилосб 5 раз.
хуй, - встретилось 7 раз.
Алсо двачесленг ведь тож легко парсится моим скриптом, если он не kolpacheque например.
Ладно, это мелочи. Меня больше интересует подход в духе бить все на гигантские массивы и копание в них в итоге. Ведь если грузишь ты войну и мир скажем этому скрипту, что по сути является не таким уж и большим объемом текста по сравнению с какой-нибудь БСЭ или собранием сочинений В.И Ленина, то он сразу будет делать огромный массив размером с эту пасту, а потом еще 1 почти такой же. И скрипт будет перебирать всё это громоздкое говно в итоге да еще и сортировать потом. Мне один товарищь сказал, что можно вообще ансетить например большие переменные как тест $text или $words после того как они перестали быть тебе нужны, это имеет смысл? Вот в чем мой главный вопрос собственно сделать вот так через массивы - норм? Или нужно сразу скажем заводить 1 массив или вообще базу, и парсить из текста слова и сразу добавлять их туда с подсчетом?
> minute
Писать лучше большими для читабельности так как это не название поля а ключевое слово SQL
HAVING нужен если используется MIN так как он работает уже после группировки. А без MIN и группировки вряд ли решишь.
> ORDER BY TIMESTAMPDIFF(minute....
Зачем так длинно? ORDER BY interval
И сортировать надо по убыванию интервала а не возрастанию.
А так, молодец, правильно решил.
А где решение про наложение сеансов?
> то он сразу будет делать огромный массив размером с эту пасту, а потом еще 1 почти такой же.
Это надо померять сколько займет памяти. Очень большие тексты встречаются редко, ну создаст он массив на миллион слов весом в 100 мегабайт, ну и фиг с ним, сервер не сломается да и память он через секунду освободит.
А если больше (например ты пишешь анализ ДНК-последовательностей из миллиардов элементов) то да, надо менять алгоритмы. Но тут по моему не требуется.
> Мне один товарищь сказал, что можно вообще ансетить например большие переменные как тест $text или $words после того как они перестали быть тебе нужны, это имеет смысл?
а смысл? Если у тебя мало памяти, ты упадешь в попытке создать их, а если ты уже создал то проблем нет. В данном случае не нужно, может когда-то это и полезно, но я такого не припомню.
> Вот в чем мой главный вопрос собственно сделать вот так через массивы - норм?
Надо протестировать на самом большом тексте и проверить. Если не упадет то зачем оптимизировать? Если упадет то да, надо менять алгорим и поверь, мне, на php такое писать будет сплошная боль и унижение.
Вообще, для оптимизации (если у тебя гигабайтные тексты) есть 2 пути:
— если не хватает памяти, используют поточный алгоритм, читающий данные блоками с диска, а не целиком. Тут он скорее всего не поможет так как нам надо держать массив частоты слов в памяти.
— используем принцип map-reduce. Разбиваем алгоритм на map и на reduce, читаем данные блоками в память, выполняем map (подсчет слов в части текста), сохраняем на диск. После чего проходимся по сохраненным map, читаем их в память и делаем reduce (суммирование результатов).
Подробнее: http://ru.wikipedia.org/wiki/MapReduce
Там есть пример подсчета частоты слов.
Преимущество этой модели в том, что сделав алгоритм соответствующий модели mapreduce, ты можешь без изменений запускать его на одном компьютере с использованием диска для хранения промежуточных данных, а можешь запускать параллельно на кластере машин. MapReduce ипользует например Гугл для обработки огромных объемов данных. Там правда не PHP обычно используется.
Например, сортировка огромных массивов (которые не влезут в память) делается похожим способом.
Заметь что unset тут никаким боком не поможет. Ты не в ту сторону смотришь.
Менять надо алгоритм а не заниматься микрооптимизациями.
> то он сразу будет делать огромный массив размером с эту пасту, а потом еще 1 почти такой же.
Это надо померять сколько займет памяти. Очень большие тексты встречаются редко, ну создаст он массив на миллион слов весом в 100 мегабайт, ну и фиг с ним, сервер не сломается да и память он через секунду освободит.
А если больше (например ты пишешь анализ ДНК-последовательностей из миллиардов элементов) то да, надо менять алгоритмы. Но тут по моему не требуется.
> Мне один товарищь сказал, что можно вообще ансетить например большие переменные как тест $text или $words после того как они перестали быть тебе нужны, это имеет смысл?
а смысл? Если у тебя мало памяти, ты упадешь в попытке создать их, а если ты уже создал то проблем нет. В данном случае не нужно, может когда-то это и полезно, но я такого не припомню.
> Вот в чем мой главный вопрос собственно сделать вот так через массивы - норм?
Надо протестировать на самом большом тексте и проверить. Если не упадет то зачем оптимизировать? Если упадет то да, надо менять алгорим и поверь, мне, на php такое писать будет сплошная боль и унижение.
Вообще, для оптимизации (если у тебя гигабайтные тексты) есть 2 пути:
— если не хватает памяти, используют поточный алгоритм, читающий данные блоками с диска, а не целиком. Тут он скорее всего не поможет так как нам надо держать массив частоты слов в памяти.
— используем принцип map-reduce. Разбиваем алгоритм на map и на reduce, читаем данные блоками в память, выполняем map (подсчет слов в части текста), сохраняем на диск. После чего проходимся по сохраненным map, читаем их в память и делаем reduce (суммирование результатов).
Подробнее: http://ru.wikipedia.org/wiki/MapReduce
Там есть пример подсчета частоты слов.
Преимущество этой модели в том, что сделав алгоритм соответствующий модели mapreduce, ты можешь без изменений запускать его на одном компьютере с использованием диска для хранения промежуточных данных, а можешь запускать параллельно на кластере машин. MapReduce ипользует например Гугл для обработки огромных объемов данных. Там правда не PHP обычно используется.
Например, сортировка огромных массивов (которые не влезут в память) делается похожим способом.
Заметь что unset тут никаким боком не поможет. Ты не в ту сторону смотришь.
Менять надо алгоритм а не заниматься микрооптимизациями.
>а смысл? Если у тебя мало памяти, ты упадешь в попытке создать их, а если ты уже создал то проблем нет. В данном случае не нужно, может когда-то это и полезно, но я такого не припомню.
Ну ладно, допустим в моем случае нет смысла, так как в 1 момент времени нужно что бы оба больших массива существовали. А если у меня допустим цепочка из больших массивов имеет место быть в программе, причем каждый после пары операций над ним уже не нужен, то такой подход имеет место быть? Что бы к концу выполнения скрипта у нас в памяти было не 10 массивов а скажем всего 2? Предпоследний и последний.
И вот еще, что плохого в том, что бы затирать переменные самими собой?
В таком воображаемом случае имеет, но unset делать необязательно, можно просто $x = null;
> что плохого в том, что бы затирать переменные самими собой?
Не понял. Это как? $a = $a ? это ничего не меняет.
это как $words = $words[0] в http://ideone.com/oTOX0e
или в любом другом скрипте когда ты пишешь в духе:
$a = sqrt($a);
$a = round($a);
и гонишь так 1 переменную далее по коду меняя её значение, и уничтожая по сути предыдущие.
Это хорошо если переменная хранит одно и тоже (например строку, которую ты постепенно преобразовываешь или число обозначающее одно и то же).
Плохо если переменная хранит разные вещи. Например массив и строку или один массив и совсем другой массив.
>Также, у тебя скорее всего есть уязвимость.
Это как исправить? Можно просто папку в исключения для php добавить?
И я (вроде бы) исправил шаблоны.
https://github.com/sqghub/uppu.ru
> Это как исправить? Можно просто папку в исключения для php добавить?
Это надо сделать. PHP можно отключить с помощью флага php_flag engine off в htaccess (и обязательно проверить), но это не очень надежно. Один анон сделал так, а потом залил код на хостинг, а там была зачем-то запрещена эта опция и у него оказалась уязвимость.
Или ты можешь перейти с apache на nginx, а он не интерпретирует htaccess, и получить уязвимость.
Для надежности стоит еще сделать «белый» список допустимых расширений, а все остальное сохранять с другим расширением. Тут правда появится проблема, что файлы при скачивании будут скачиваться под другим именем, но ее можно решить хитрым трюком с mod_rewrite, сделав чтобы по ссылке
http://example.com/download/diskname.txt/savename.php
Отдавался бы файл /upload/diskname.txt (при этом браузер берет имя для сохранения из последнего компонента ссылки, то есть savename.php). Так же можно решить проблему если например имя содержит русские буквы, а PHP коверкает их при сохранении.
То есть мы сохраняем файл как diskname.txt, а отдаем с любым желаемым именем за счет манипуляций с URL.
Также, проверь, работают ли файлы с пробелами в имени и с русскими буквами.
Кстати, заметь в моей идее есть уязвимость: злодей может закачать в папку свой .htaccess (затерев наш), а с помощью него он заставить сервер любой файл, включая картинки, интерпретировать как php скрипт. Это тоже надо учесть.
Потому там где важна безопасность, правила надо писать в конфиге сервера (который находится не в веб-папке), а интерпретацию htaccess запрещать.
Я кстати, подозреваю, что такая уязвисть (загрузка htaccess) может быть во многих самодельных php-скриптах.
И есть еще одна особенность Апача (она не всегда работает, зависит от конфигурации): когда Апач встречает незнакомое расширение, он смотрит на расширение перед ним. То есть файл
hello.php.lalala
Он воспримет как php-файл, хотя твой скрипт например увидит расширение lalala и пропустит его.
Если в скрипте загрузки есть «белый» список разрешенных расширений и lalala он тоже не пропускает, надо найти расширение которое есть в белом списке, но которое не знает Апач. Я знал раньше одно такое расширение :) типа файла, которое разрешено в некоторых форумных движках но которое не знает Апач с настройками по умолчанию, но тут писать его не буду.
В общем, тема загрузки файлов в системе «Апач + PHP» или «nginx + php» конечно содержит много подводных камней, о которые можно легко споткнуться новичку.
Поясню, если ты не в курсе, файл .htaccess — это файл, который позволяет изменить настройки Апача в отдельной папке и ее подпапках.
Плюсом htaccess является то, что ты можешь изменить настройки сервера в пределах одной папки, и что для этого не надо править конфиг (не нужны права админа, плюс новичок может не знать как это делать, а тут достаточно файл скопировать).
Минусом — снижение безопасности если злоумышленник может закачать на сервер такой файл, он может его захватить.
>Также, проверь, работают ли файлы с пробелами в имени и с русскими буквами.
Работают.
А вот про остальное я сходу не понял, но думаю, что вкурю. Вкурю и сяду за комментарии.
https://github.com/sqghub/uppu.ru/blob/master/index.php#L30
Это бардак, много кода свалено в одну функцию, простыня какая-то, надо подумать что с этим делать.
Например, можно это вынести в какие-то методы в каком-нибудь классе. Можно вообще сделать класс FileInfo например, который представляет хранилище информации о переданной ему картинке/аудио, умеет определять нужные типы, и содержит методы типа
isImage()
isAudio()
getImageWidth()
getAudioInfo()
....
и передавать этот объект в шаблон.
Или же можно сделать класс-помощник, у которого будут методы
isImage(File $file)
isAudio(File $file)
getImageWidth(File $file)
.....
Или может быть можно часть этих методов перенести в сам класс File.
код получения ссылки на файл должен быть в отдельной функции.
Также, id3 не очень легкая библиотека и не надо ее вызывать при каждом просмотре файла. Лучше вызвать ее один раз при загрузке и все. Вообще, лучше метаданные о файле определять один раз и хранить в БД.
Подумай, как лучше.
> if ($fileType == 'image') {
Используй альтернативный синтаксис с двоеточием
Вместо форматировния через <br> используй тут таблицу из одной колонки или список определений (он тут подошел бы) на основе dd/dl/dt
Не исплоьзуй h2/h3 для задания шрифта
> <?
Можно использовать либо <?= либо <?php
Функцию html не определяй в шаблоне, определи ее либо в index.php в конце где-нибудь, либо в отдельном файле functions.php. Не определяй функции в шаблонах никогда.
> value="104857600" />
В языке HTML слеш тут не пишется. Он пишется в XML/XHTML.
> header("Location:
Шаблоны для генерации html-кода страниц. Редирект надо делать прямо в index.php причем у Слима есть метод redirect
> style="width:98%"
Ой, это совсем плохо, это уродливый костыль которым ты пытаешься прикрыть незнание CSS.
> style="width:<?=$width?>px;height:<?=$height?>px"
Контейнер может определять свои размеры сам за счет CSS (например сделав его inline-block или float).
https://github.com/sqghub/uppu.ru/blob/master/index.php#L30
Это бардак, много кода свалено в одну функцию, простыня какая-то, надо подумать что с этим делать.
Например, можно это вынести в какие-то методы в каком-нибудь классе. Можно вообще сделать класс FileInfo например, который представляет хранилище информации о переданной ему картинке/аудио, умеет определять нужные типы, и содержит методы типа
isImage()
isAudio()
getImageWidth()
getAudioInfo()
....
и передавать этот объект в шаблон.
Или же можно сделать класс-помощник, у которого будут методы
isImage(File $file)
isAudio(File $file)
getImageWidth(File $file)
.....
Или может быть можно часть этих методов перенести в сам класс File.
код получения ссылки на файл должен быть в отдельной функции.
Также, id3 не очень легкая библиотека и не надо ее вызывать при каждом просмотре файла. Лучше вызвать ее один раз при загрузке и все. Вообще, лучше метаданные о файле определять один раз и хранить в БД.
Подумай, как лучше.
> if ($fileType == 'image') {
Используй альтернативный синтаксис с двоеточием
Вместо форматировния через <br> используй тут таблицу из одной колонки или список определений (он тут подошел бы) на основе dd/dl/dt
Не исплоьзуй h2/h3 для задания шрифта
> <?
Можно использовать либо <?= либо <?php
Функцию html не определяй в шаблоне, определи ее либо в index.php в конце где-нибудь, либо в отдельном файле functions.php. Не определяй функции в шаблонах никогда.
> value="104857600" />
В языке HTML слеш тут не пишется. Он пишется в XML/XHTML.
> header("Location:
Шаблоны для генерации html-кода страниц. Редирект надо делать прямо в index.php причем у Слима есть метод redirect
> style="width:98%"
Ой, это совсем плохо, это уродливый костыль которым ты пытаешься прикрыть незнание CSS.
> style="width:<?=$width?>px;height:<?=$height?>px"
Контейнер может определять свои размеры сам за счет CSS (например сделав его inline-block или float).
>это уродливый костыль которым ты пытаешься прикрыть незнание CSS.
Я не пытаюсь прикрыть. Я его не знаю.
>Или может быть можно часть этих методов перенести в сам класс File.
Наверное, я перенесу их все.
>Вообще, лучше метаданные о файле определять один раз и хранить в БД.
Мне сходу не приходят мысли в голову, как это сделать.
Бтв, something.php - не выполняется, something.php.bla - выполняется. Беда.
>Бтв, something.php - не выполняется, something.php.bla - выполняется. Беда.
Это победил.
Я не уверен. htaccess переопределяет настройки сервера. Ты можешь в нем обращение к несуществующему файлу в одной папке переписать на выполнение другого файла как скрипта.
Я сделал такой архив для экспериментов, где злоумышленник контроллирует файл htaccess, но выполнить код мне не удалось: http://rghost.ru/58966601
Прямое обращение к файлу evil.php не дает выполнения кода.
Файл в папке upload по задумке контроллируется злоумышленником и обращения по URL типа /evil-htaccess/upload/1 вызывают срабатывание команд в нем.
Но то, что у меня ничего не получилось, не значит что это безопасно так как я плохо знаю Апач, у него куча модулей + куча настроек у PHP, так что может кто-то более опытный и найдет способ это использовать. Например, в Апаче есть язык SSI, который выполняется в shtml-файлах: https://ru.wikipedia.org/wiki/SSI_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)
Плюс если в Апаче есть уязвимости при обработке каких-нибудь специмволов в конфиге (или например сверхдлинных строк) то злоумышленник сможет выполнить свой код внутри Апача.
То есть явного способа как использовать это, у меня нет, но интуиция подсказывает что возможность загрузить свой htaccess небезопасна.
Вот пример эксплойта на основе загрузки htaccess в другом прилжении: http://www.exploit-db.com/exploits/17644/
Там сервер перенастраивется чтобы воспринимать gif файл как php.
В общем, учитывая сложность и число разных настроек и модулей в Апаче, если порыться, наверняка что-то можно найти. Как минимум ты можешь читать исходники php файлов, включая конфиги с паролями, таким образом.
Я тут чуть поднапрягся, и эксплойт заработал. Мы можем поместить php код в сам htaccess и тем самым решить проблему.
http://rghost.ru/58966705
Изучи, если что-то непонятно, задавай вопросы. Распаковать надо в корень сайта, открыть URL /evil-htaccess/upload/2
Отключить выполнение htacccess в дочерних папках вроде бы можно директивой
Options None
(у меня сработало), но все равно мораль истории в том что система htaccess файлов (и система загрузки файлов в php) открывает простор для уязвимостей и разработчики (в твоем лице) об этих возможностях не знают. Потому в идеале настройки Апача должны быть в конфиге, а htaccess отключен (но мы этого делать не будем).
>>403714
> Я его не знаю.
Ну ладно, делай пока как умеешь, но потом хорошо бы подучить. Все же какие-то простые вещи ты должен уметь делать без помощи верстальщика и без написания кода от которого у него кровь из глаз потечет.
>>403718
Думаю, это не очень расширяемо, в данном случае проще хранить JSON с данными в отдельной колонке. Этакой NoSQL подход.
>в данном случае проще хранить JSON
Вот что это такое - я совсем не имею представления.
Имей в виду, что «объект» в JSON — это не настоящий объект с классом и методами, а просто неупорядочнный ассоциативнй массив из пар «ключ-значение» (а массив в JSON — это упорядоченный массив с цифровыми ключами идущими от 0 до N).
В какой еще файл? Нет, идея в том что ты берешь массив с данными, преобразуешь его в строку в формате JSON и сохраняешь в БД. А при загрузке из БД то же самое в обратном порядке.
Ну и конечно можно это все делать в методе какого-то класса.
А если я в json_encode передам объект, то что получу на выходе?
Если в json_encode передам что-то, то на выходе я получу массив, так да?
>преобразуешь его в строку в формате JSON и сохраняешь в БД
Отдельную таблицу все же делать. Вроде бы все понял.
JSON это формат сериализации.
Сериализация это преобразование сложных структур (массивов с данными например) в строку которую можно сохранить в файл, в Бд, передать по сети. Десериализация это обратный процесс.
PHP поддерживает как JSON, так и свой свобственный формат функцией serialize. Но JSON мне нравится больше так как он человекочитаем и тебе проще будет отлаживать все это. Ну и плюс, он поддерживается во многих языках и более универсален.
> Объект в JSON - это как структуры в си?
Что-то вроде. Или это как php-массив только неупорядоченный.
> А если я в json_encode передам объект, то что получу на выходе?
Скорее всего он превратит объект в массив из свойств (не знаю, публичных или любых) и его уже закодирует. Поэкспериментируй и проверь.
> Если в json_encode передам что-то, то на выходе я получу массив, так да?
Либо массив либо объект stdObject c кучей свойств который по сути тот же массив. Там есть флаг чтобы возвращал всегда массив. Поэкспериментируй.
Мотивация неправильная. Не стоит делать отдельную таблицу ради того чтобы делать отдельный класс. Таблицы соответствуют сущностям, 1 вид сущности — 1 таблица. Мапперы соответствуют таблицам, 1 таблица = 1 маппер.
Может лучше отдельный класс, заполняющий поле mediaInfo в File? Тогда в File можно поместить разные методы типа isImage и тд. Или же можно сделать класс MediaInfo, и помещать его экземпляр в File. Или сторонний класс.
Огромный это 1000+ строк
Вынеси из него все, что не касается работы с базой данных, в класс FileService, если он тебе кажется огромным.
Я передумал. Не такой уж и огромный.
>this.variable.field = 1
>тут явно 3 слова: this, variable, field
нет, это же одна переменная, это одно слово
>А если и может то удобнее использовать исключения, так как с false твоя программа обрастает ненужными ифами, можешь почитать: https://gist.github.com/codedokode/65d43ca5ac95c762bc1a
плохо что ты для программы в 20 строк с 1 методом советуешь использовать исключения. это признак говнокода.
исключения нужно выбрасывать в исключительных случаях. тот же макконел об это пишет.
если можно обработать ошибку простой проверкой на фолс - нужно делать так.
>А французских, немецких? С их странной буквой ß ?
именно поэтому нужно разделять по пробелам
аргумент с this.variable.field = 1 инвалид - это одно слово
>PHP_EOL
вообще не понял о чём речь. PHP_EOL выше уровнем чем \n
мы же не экономим байты и не пишем на ассемблере. нет ни одной причины не использовать PHP_EOL
>>403693
>пробелы это больше гемора
только если делать это неправильно
разбить пробелами, тримить всё кроме алфавита
делить по пробелам - единственный и самый правильный вариант
>Что ты скорее всего не особо ответственный и думал бы как скорее на более высокооплачиваемую работу перейти.
нихуя не понял
меня в конторе держат как раба - я хочу перекатится на норм зарплату - я безответственный?
>>403696
В общем спасибо за ответы, алсо вот переделал скрипт слегка.
http://ideone.com/beC7xu
Потренился делать сосвойствами юникода и все такое.
Вообще тут такие классные все сидят, обсуждают уязвимости своих проектов и прочие ништяки, а я еще даже учебник не прошел, завтра бтв иду на своё первое собеседование джуном в 26 лет и примерно понимаю что я там насосусь по полной, ведь еще очень много чего не знаю. Но думаю меня это смотивирует. Ведь чем сидеть дома сычевать, лучше на собеседовании насосаться и прийти прогуглить от баттхерта вопросы на котороых засыпался и начать учить что-то новое сразу, да? Или лучше сидеть поготовиться подольше?
>Вообще тут такие классные все сидят, обсуждают уязвимости своих проектов и прочие ништяки
Классный тут только Оп. Я кроме этого обменника на пхп всего пару задач и решил.
>завтра бтв иду на своё первое собеседование джуном
Как решился? Я вот думаю в таком темпе еще минимум пару месяцев надо изучать, чтобы вообще решить, что я что-то умею.
Он единственный, кто что-то разжевывает здесь. Так что больше нечего поглощать.
>Как решился?
Оче просто, нет денег совсем, живу на шее родителей. Не работаю уже почти пол года в сумме, вот и всё. Продуктивность изучения дома у меня крайне маленькая, очень много отвлекаюсь на всякие двачи и игоры. Вспоминая опыт устройства эникеем думаю что это меня смотивирует. Ну а если сфейлю то может опять эникеем буду устраиваться, там хоть и не сидишь не кодишь, но деньги платят хоть какие-то, плюс дисциплина и осознание ценности своего времени.
>Я вот думаю в таком темпе еще минимум пару месяцев надо изучать, чтобы вообще решить, что я что-то умею.
Мне в своем теперешнем темпе нужно будет пол года наверное. Хотя приличный человек думаю за две недели бы смог осилить те места в которых я проседаю: ООП, основы JS, немного опыта с Linux и MySQL. В общем буду надеятся на то что меня либо будет собеседовать технически подкованный человек, который будет засыпать вопросами, либо даже если и HR, то дадут тестовое задание, которое можно будет задротить неделю насилуя гугол и засыпая этот тред дибильными вопросами.
В итоге думаю толк будет.
>Это незачем делать при каждом вывзове функции. Это надо вынести из нее. Или написать свою функцию isArray
>Неправильно используешь isArray. Это функция а не свойство массива. Ты протестировал свой код? Не работает же.
http://jsfiddle.net/81n7yn73/3/
>Незачем создавать еще переменную, можно использовать func
http://jsfiddle.net/jnr1ctbb/1/
>После if надо использовать {}, i =0 удобнее поместить в for так как оно к нему относится. Так, сама задача решена хорошо.
http://jsfiddle.net/eutonLL3/1/
>После for надо использовать {}, также тут можно передавать в apply сразу arguments без цикла и массива
http://jsfiddle.net/782ke5fe/1/
>>403686
>Слишком сложно. Давай без for
Ок, переделаю
>Я обновил задание, поменяв порядок аргументов (почему? потому что так в lodash сделано).
Какая разница?
>Надо чтобы работало с любой переданной функцией а ты прописал isEven
http://jsfiddle.net/m977t83x/2/
>>403689
>думаю почему это быдлокод, объяснять не надо?
Объясни пожалуйста
>Это незачем делать при каждом вывзове функции. Это надо вынести из нее. Или написать свою функцию isArray
>Неправильно используешь isArray. Это функция а не свойство массива. Ты протестировал свой код? Не работает же.
http://jsfiddle.net/81n7yn73/3/
>Незачем создавать еще переменную, можно использовать func
http://jsfiddle.net/jnr1ctbb/1/
>После if надо использовать {}, i =0 удобнее поместить в for так как оно к нему относится. Так, сама задача решена хорошо.
http://jsfiddle.net/eutonLL3/1/
>После for надо использовать {}, также тут можно передавать в apply сразу arguments без цикла и массива
http://jsfiddle.net/782ke5fe/1/
>>403686
>Слишком сложно. Давай без for
Ок, переделаю
>Я обновил задание, поменяв порядок аргументов (почему? потому что так в lodash сделано).
Какая разница?
>Надо чтобы работало с любой переданной функцией а ты прописал isEven
http://jsfiddle.net/m977t83x/2/
>>403689
>думаю почему это быдлокод, объяснять не надо?
Объясни пожалуйста
smile_for_bright
Кстати, поясни что ты сейчас умеешь? Хочу сравнить со своими знаниями и решить правильно ли я их оцениваю.
мимотакойжекакиты
Да ничего не умею. Я сделал задачки на сортировку, сочитания и задачку про лайки. И вот сейчас файловый обменник делаю.
В верстке - совсем ноль.
Что за задачки их можно найти выше в треде? впервые в этот тред зашёл. А например там гостевую книгу с базой данных можешь замутить или там примитивный блог например?
>>403843
>>403835
я не хочу говорить что вы занимаетесь хуйнёй, но вы пробовали на хх или в супержобе найти вакансии стажёра? например "требуется пхпПРОГРАМИСТ без опыта"
там будет в требованиях написано КОКОКО ТРЕБУЕТСЯ ДОХУЯ, вы смотрите только на то что "програмист без опыта". какие к нему могут быть требования? да никаких.
вам туда и нужно.
>Что за задачки их можно найти выше в треде?
Скорее в прошлом треде. >>399201
Про лайки здесь: https://gist.github.com/codedokode/10539213
>А например там гостевую книгу с базой данных можешь замутить или там примитивный блог например?
Думаю смогу, но если выкладывать сюда, то Оп быстро найдет ошибок. Хотя гостевая, наверное, совсем простой будет.
Бтв, Оп, про древовидные комментарии: я продумал и как их хранить, и как их выводить, я не знаю только как их ввести. Чтобы форма открылась под нужным комментарием и откуда-то брала его айди. Подсказками не поможешь?
Прям совсем никаких? Кстати а сколько в среднем происходит переход со стажёра на джуниора?
>но вы пробовали на хх или в супержобе найти вакансии стажёра
Меньше недели опыта, рановато в стажеры. И да, в моем мухосранске и не будет вакансий, как мне кажется.
>Про лайки здесь:https://gist.github.com/codedokode/10539213
Инфу сам вбиваешь в базу данных? Цель просто вывести необходимую инфу?
Насчет хранить, прочитай этот пост, вдруг что новое найдешь: https://gist.github.com/codedokode/10539720
Нужен яваскрипт. Если не знаешь яваскрипта, то сделай через ссылки, то есть под каждым комментарием есть ссылка вида:
/files/1234/?reply=123
В ответ на которую сервер отдает страницу с раскрытой формой в нужном месте.
нет, я начал программировать в 23 года (до этого и не пробовал). мой совет - месяца 3 потратьте на очень хорошую подготовку (всмысле, дрочите целыми днями ЯП, БД, читайте, пишите код) - не надо сидеть и дрочить хх в надежде увидеть заветное "без опыта". Вот через пару месяцев можешь начинать.
Стажёров берут строго на вырост, поэтому ты должен заинтересовать работодателя, и ты должен показать свою охуенную кривую обучения.
Сам я начинал с джаваскрипта - дрочил его 2 месяца, после чего меня взяли на работу.
Я читал. И до того как читал, решил, что будет >метод Adjacency List
>Нужен яваскрипт. Если не знаешь яваскрипта
Я не знаю. Но так не хотелось. Потом вдруг выучу яваскрипт и переделаю.
нет никаких конкретных градаций
каждая компания решает для себя кто джуниор, кто стажёр
не хочу вас огорчать, но в ООО-ГОВНОСАЙТ, куда попадёт большинство из сидящих итт, нет джуниоров и сеньёров. там есть разработчик и стажёр, и всё, как в моей конторе.
>>403852
ты сначала посмотри вакансии, ты можешь всю жизнь проебать пока тебе будет КАЗАТЬСЯ
неделя с момента когда ты первый раз <?php написал?
с одной стороны мало конечно, но с другой стороны может ты умный
>взаимных лайков
Есть колонка где хранится количество поставленных лайков, есть колонка где хранится количество полученных лайков. Как здесь выделить взаимные?
Понятно, надо значит выучить больше операторов sql а то я только самые очевидные знаю для записи и вывода из баз данных.
Ты решай, как можешь, и выкладывай. Оп умеет направлять в нужную сторону.
Задача про кинотеатр на SQL: >>402577
Задача на MySQL + PHP + все остальное: https://gist.github.com/codedokode/d7e7f11449fc3bcb24b4
>>403880
Там в задании перечислено что в идеале надо знать, все операторы написаны.
>>403880
Если конкретнее, от тебя требуется написать
— команды CREATE TABLE создающие таблицы
— INSERT который их заплняет
— SELECT который строит нужную выборку
Так как это задача на SQL то и в ответ на нее ожидается скрипт на языке SQL. Желательно загруженный на сайт sqlfiddle для удобства просмотра.
> В общем, я вижу, что ты то ли учился по каким-то сомнительным урокам, либо, что вероятнее, ты пропускал темы и мало решал задач. Если ты хочешь научиться писать нормально, то быстро, к сожалению не получится. Надо прорешать весь мой учебник + решить сложные дополнительные задания на работу с фреймворками.
Хм. Ну, тогда порешаю задачи из твоего учебника. Просто у меня (ну, мне так кажется) есть проблемы с логикой, я не понимаю сложные математические формулы с ходу и так далее, а все кажущиеся нерешаемыми задачи при написании кода (а такими кажутся большинство задач) вызывают дикую апатию и, поэтому, есть подозрение, что писать код — не для меня, но с другой стороны, мне нравится смотреть на результат. Хотя, это очень слабый аргумент, на результат любой деятельности смотреть приятно. Вот. Поэтому определиться самостоятельно не выходит. Хм. Короче, мне нужно выяснить — могу я это или лучше уйти познавать что-то иное. Конечно, можно упорным задроством, но лучше не нужно, ведь так?
В общем, порешаю твои задачи и ты мне скажешь. (Я надеюсь).
У меня тоже жуткая апатия писать, я делаю перерывы недельные, вот кое как добрался до кошек мышек, с ооп как-то интереснее стало изучение, и приятно смотреть на аккуратный код. С другой стороны я просто человек ленивый и чем бы я не занимался, мне это быстро надоедает.
Именно так. Я боюсь, что зайду в тупик, при решении задачи, и поэтому боюсь начинать. Так и со всем остальным. По сути в этом и причина прокрастинации у многих людей - боязнь, что не получится.
ты не понял ничего
страх не причём
просто непонятно что делать, непонятно где искать ответ и т.д.
>Конечно, можно упорным задроством, но лучше не нужно, ведь так?
Вся суть погромирования это упорное задротство. Научившись решать типовые задачи уже можно отключать мозг и просто нажимать на кнопки, но с каждым новым левелом сложность повышается (если ты, конечно, не застрял в НИИ Говна и Торфа) и бугурт непонимания никуда не исчезает. Больше двух лет этим уже занимаюсь и никакого конца не вижу – либо ты останавливаешься в развитии и просто нажимаешь на кнопки, либо сражаешься со своим бугуртом каждую неделю. Хорошая новость – с каждым годом задротство дается все проще и проще, и в начале пути я на простой задаче мог встать в тупик на целую неделю и нихуя не понимать, кодируя сутками напролет без сна, чтобы не сорвать обещанные сроки – то теперь навыки декомпозиции любой задачи сильно возросли и понимание веба как такового тоже, так что любые "тупики" длятся не долго, а сроки планируются гораздо точнее.
Насколько я ненавижу погромирование в моменты бугурта и марафонов задротства, настолько же осознаю, что погромирование – лучшее что случилось со мной в жизни.
нихуя не умеем больше же
Ну я понимаю, как можно задрочить верстку. Но вот как задрочить логику - не понимаю. Она же либо есть, либо её нет.
Что значит "задрочить логику", "либо есть либо нет"?
Под задрачиванием погромирования я имею ввиду траты большого количества времени на эту хуйню практически без остановки.
>логику
там не нужна логика
ты просто пишешь код, тебе говорят где ты пишешь не так
потом пишешь снова, и снова исправляешь
потом приходишь на двач в пхп тред и строишь из себя эксперта, поясняешь ньюфагам за жизнь, собеседования и недостатки пхп
и никто не догадается что ты и другой анон, который плачется о том что получает 18к - один и тот же человек.
Мне кажется это толстота такая, не может человек иметь такое чсв, получая 18к.
>Кто говорит?
оп
а вообще мне кажется лучше всего устроится на работу, только не в ООО ГОВНОСАЙТ, а куда-нибудь серьёзнее, где тебе будут пояснять
Нет, это ты просыпаешься и бежишь к начальнику. Говоришь ему – повышай зарплату иначе я уебываю в более элитную шарагу, потому что навык мой возрос.
няша, ну мы же на дваче
я сейчас морально готовлюсь к этому шагу
проблема в том что на мне крупный проект, который я пишу больше полугода, и вот так просто "я уёбываю" - будет неправильно
начальник пояснял что КРИЗИС и можете хуй сосать а не зп просить
я думаю бесполезно унижаться перед ним
>>403940
аргументируй, маня
я адекватно общаюсь, поясняю анонам кодом, спорю с опом, неного ебанут, и не пощу смищные мемчики
я просто эталонный анонимус
>проблема в том что на мне крупный проект, который я пишу больше полугода
И без тебя там все развалится? Чо вы там, адронный коллайдер разрабатываете раз ты такой незаменимый?
>И без тебя там все развалится? Чо вы там, адронный коллайдер разрабатываете раз ты такой незаменимый?
сначала "делаем быстрее, баги будем чинить за их же деньги ахаха"
потом никто не может разобраться в говнокоде полном костылей
кто виноват? Я БЛЯТЬ ВИНОВАТ! Я ЖЕ МАКАКА, МЕНЯ ЗАЕБАЛИ БЫСТРЕЕ БЫСТРЕЕ, постоянно изменяются требования, НИКТО НЕ МОЖЕТ ПИСАТЬ ИДЕАЛЬНЫЙ КОД С НУЛЯ ПОД ТРЕБОВАНИЯ КОТОРЫЕ НЕИЗВЕСТНЫ.
-РЕФАКТОРИНГ? НЕТ, НУЖНЫ ФИЧИ.
-НУ ЛАДНО, НЕДЕЛЮ.
КАКУЮ НЕДЕЛЮ, УЕБАНЫ??? я писал этот код блять 4 месяца, нихуя я за неделю не улучшу.
ну ты понял.
Перекатывайся во фронт. У меня товарищ в мухосранске 250к получает удаленно чуть меньше 50к с опытом чуть больше года. Правда он работает 6 дней в неделю часов по 10.
10 часов в неделю? Или 10 часов в день? Это же тогда вообще лоулайфер, нахуй так жить.
>во фронт
работать много не проблема
дело в следующем:
1) я угараю по бэкенду, абстракции, фабрики, интерфейсы, вот это всё.
2) у меня багет от фронта. КОКОКО СДВИНЬ НА ПИКСЕЛ ВЛЕВО
КОКОКО ИЕ8 КНОПКА СЪЕХАЛА
идите нахуй со своим фронтом, это пиздец ебаный
3) я боюсь что не справлюсь с общением с заказчиками. меня сильно напрягает это. ставить сроки, обсуждать, показывать себя профессионалом
По работе нужно установить Апач 2.2 и php 5.3 и подружить это дело с Ораклом.
Сейчас на этапе LoadModule php5_module
при запуске httpd.exe появляется ошибка - он не может найти директорию для модуля, хотя адрес точно правильный. Подскажите как это лечить .
и какие еще могут возникнуть проблемы при настройке?
кому нибудь доводилось работать на php с базами Oracle?
ох блять, вопрос уровня "сделайте всё за меня" и "вытащите всю информацию из меня щипцами, сам я ничего не скажу" в одном! просто комбо
Я не знаю чего ты заморачиваешься. Если чувствуешь что действительно весь год въебывал и повысил свой скилл – просто пиздуй в другую контору или на фриланс, год это довольно много.
Начальникопроблемы тебя ебать вообще не должны – если бы он действительно хотел качественный продукт, то не нанимал бы для его разработки человека с практически нулевым опытом за минимальный российский прайс.
Спасибо заранее
ему не нужен качественный продукт
он нанимает объзьян за 15к чтобы самомоу заработать
моя проблема - я хикка и мне тяжело сменить коллектив, идти договариваться, идти на собеседования и т.д.
Я, впрочем, вообще не понимаю как можно тратить на что-то по 10 часов в день дольше недели и не сойти при этом с ума. Этот товарищ фронтендщик либо пиздит, либо совсем поехавший аутист, либо скоро сойдет с ума от стресса и переработки. Никто 10 часов в день не работает, это ОГРОМНАЯ нагрузка.
я могу работать по дохуя часов, если одновременно двачую
пощу пост, работаю, жду ответа
совершенно не устаёшь
В день конечно
>>403953
>1) я угараю по бэкенду, абстракции, фабрики, интерфейсы, вот это всё.
Согласен, в этом есть свой интерес.
>2) у меня багет от фронта. КОКОКО СДВИНЬ НА ПИКСЕЛ ВЛЕВО
КОКОКО ИЕ8 КНОПКА СЪЕХАЛА
идите нахуй со своим фронтом, это пиздец ебаный
А вот это от проекта в проекту на самом деле. Плюс вот это
>КОКОКО ИЕ8 КНОПКА СЪЕХАЛА
Вообще по дефолту требование, сейчас большинство просит ие8+
>3) я боюсь что не справлюсь с общением с заказчиками. меня сильно напрягает это. ставить сроки, обсуждать, показывать себя профессионалом
Это тоже от конторы к конторе разнится. В идеале ты вообще заказчика не видишь.
>>403960
Он не так долго работает в таком режиме. Месяца 3. Плюс у него частный дом с качалкой, всегда можно расслабиться. Плюс 50к это более чем в два раза превышает среднюю з/п в том мухосранске.
Не факт, что для него это нагрузка.
Может он удовольствие от этого получает и для него это хобби. Ну или в доту режется половину времени.
В любом случае, если человека действительно что то не устраивает. Он съёбывает бысто, решительно.
Ох, ну тогда страдай. Без социоблядства [умеренного] ничего не получится. Потом все равно придется вливаться в коллектив, т.к. обычно более-менее серьезные проекты в одиночку не делаются. Придется обсуждать технические решения, отстаивать свою точку зрения, помогать другим и спрашивать помощь самому при необходимости. Понимать цели заказчика и смысл продукта, обсуждать то что не понятно, даже если это не касается программирования. Не говоря уже о том, что нужно изначально знать цену своих скиллов и договариваться с работодателем.
Это при условии что ты не хочешь быть простой макакой, которой дают отдельный блок кода, который даже не понятно зачем нужен, т.к. ты слишком далек от архитектуры и принятия решений.
Ты не совсем правильно понял. Для него это шанс съебать из мухосранска, его все вполне устраивает на данном этапе.
Это не работа, 80% времени уходит на двачи. Я знаю, потому что прямо сейчас так делаю.
Попробуй засекать таймер и хуярить вообще ни на что не отвлекаясь, а интернетом пользуясь только по делу.
У меня в таком режиме не больше 4 часов в день получается.
>>403963
Даже на хобби последний раз я тратил столько времени лет в 16, когда в WoW круглые сутки задрачивал. Ну и в начале моего пути погромиста, когда не мог рассчитать сроки – но это было вынужденно и я потом долго отходил от такой нагрузки. Не в кайф, в общем.
В доту он не играет, лол. И на двачах не сидит. Но это в любом случае не офисная работу, я за те же деньги сижу в офисе в дс, 5 дней в неделю по 7 часов, из которых работаю даю бог 4. Я все это начал к тому что за фронт нынче платят поболее чем за бэк на пэхе.
всё из-за того что пыху заполонили макаки, которые больше нихуя не умеют
На начальных порах больше всего платят за fullstack, т.к. в этом случае человек хотя бы понимает как все это говно работает. Ну а там уже ничего не мешает специализироваться на чем-то больше, а другую работу делать при необходимости.
С опытом все сильно меняется, а твоя специализация может усиливаться. Хорошим бэкендерам платят дохуя, т.к. по сути они и проектируют все приложение.
Прокачанные фронтендеры переходят на javascript mvc и тоже неплохо зарабатывают.
Fullstack хорошо понимает и тех и других, выступает связующим звеном и тоже проблем с деньгами не испытывает.
В общем, везде платят за скиллы.
>А где решение про наложение сеансов?
тут >>403285
Опять я запоролся.
- список фильмов, общее число посетителей за все время, среднее число зрителей за сеанс и общая сумма сбора по каждому, отсортированные по убыванию прибыли. Внизу таблицы должна быть строчка «итого», содержащая данные по всеи фильмам сразу.
среднее число зрителей за сеанс, это как? Что б сосчитать сколько за каждый сеанс нужно группировать сеансы. Что бы дальше посчитать среднее за сеанс, мне надо сгруппировать уже фильмы. Можно ли группировать дважды в MySQL? Ох пойду дальше теорию читать.
Пока не практикуешся теория не усваивается. Без теории практика не выполняется какой то замкнутый круг.
И со строчкой итого ещё не разобрался
http://sqlfiddle.com/#!2/621c43/42
http://sqlfiddle.com/#!2/621c43/43
Да, я знаю, код в шаблонах, я его уберу оттуда. Верстка отвратительная, первый кусок кода на яваскрипте тоже.
https://github.com/sqghub/uppu.ru
>PHP Notice: Undefined offset: -1 in /home/bui2XE/prog.php on line 13
Читать ошибки для слабаков?
ОП, ответь пожалуйста ньюфагу на ньюфажный вопрос: в чем разница между AWS, Heroku и Github, кроме того что на гитхабе можно пилить совместные проекты, смотреть код чужих и все такое?
А двачевать капчу, фильмы смотреть, музыку слушать или в игры играть ты может по 10 часов в день? А как что-то полезное сделать — так тяжело?
Если ты молодой и здоровый, то в принципе какое-то время можно так работать без всяких проблем. Это же не физическая работа.
Да и я думаю, этот анон прокачает навыки и на другую работу устроится.
Смотри допустим фильм «кровавая медуза» показывали 3 раза, в первый раз пришло 20 человек, во второй 30, в третий 40.
> общее число посетителей за все время
20 + 30 + 40
> среднее число зрителей за сеанс
среднее(20, 30, 40) = 30
> общая сумма сбора по каждому
Ну это понятно, 20 × цена билета + 30 × цена билета + 40 × цена билета
> И со строчкой итого ещё не разобрался
Во-первых есть UNION который умеет соединять вертикально 2 таблицы. Но в этом случае тебе может быть он не нужен так как у GROUP BY есть интересная опция WITH ROLLUP для подведения итогов.
> Можно ли группировать дважды в MySQL?
Нет, но можно группировать по нескольким полям если надо. Или можно сделать двойную группировку через подзапрос SELECT FROM (подзапрос) GROUP BY но тут явно это не требуется.
GitHub — это сервис предоставляющий git-репозиторий (место для хранения кода) и удобные средства для просмотра кода, истории изменений, сотрудничества (ты можешь форкнуть чей-то проект, можешь исправлть ошибки и присылать патчи, сообщать о багах и тд).
AWS — это облачный сервис. То есть сервис, предоставляющий в аренду за деньги виртуальные машины, с которых ты можешь например раздавать файлы или на которых ты можешь разместить сайт. Ну вообще ты туда можешь установить что угодно. Можешь например сервер майнкрафта поставить.
Heroku — хостинг для руби-проектов. Ты можешь арендовать на нем виртуальные машины чтобы поднять сайт на руби (и может других языках, но первоначально он для руби делался).
Отличие «облачных» хостингов от обычных в том, что там ты можешь, если нужно, в течение нескольких минут взять в аренду и развернуть дополнительные машины, например если сайт не спраляется с нагрузкой (и если твой код поддерживает масштабирование). В то время как на обычных хостингах, где ты арендуешь реальное железо, есть плата за установку и время пок люди подключат и настроят сервер, это может легко день-два занять. Ну и на облачных хостингах ты можешь арендовать маленькую дешевую машинку. в то время как в обычных — мощные дорогие сервера.
То есть разница между github и heroku/aws в том, что это разные вещи.
Спасибо за ответ.
> нет, это же одна переменная, это одно слово
Это не одна переменная. Это переменная + 2 названия полей.
> плохо что ты для программы в 20 строк с 1 методом советуешь использовать исключения. это признак говнокода.
Нет
> исключения нужно выбрасывать в исключительных случаях
Это и есть исключительный случай — в функцию работающую со строками программист передает не-строку. Надо сказать ему об этом, и стандартный способ для этого исключение. Обрабатывать это исключение не требуется.
Если передана пустая строка, я не вижу тут ошибки, логично возвращать что 0 слов.
Исключения как раз были придуманы чтобы избавиться от уродливых return false/ if $result === false
> если можно обработать ошибку простой проверкой на фолс - нужно делать так.
Нет. Если ты неправильно используешь функцию, программа должна падать, и единственное решение — исправить код.
> именно поэтому нужно разделять по пробелам
Нет. Наша цель не посчитать число любых разделенных пробелами символов, а посчитать число слов.
> мы же не экономим байты и не пишем на ассемблере. нет ни одной причины не использовать PHP_EOL
Используй. А я буду \n исплоьзовать.
> разбить пробелами, тримить всё кроме алфавита
Это — хорошо .
Сколько тут слов? И сколько ты получишь элементов?
Если ты перекатываешься ты должен нормально закрыть проект и передать его тому, кто будет им заниматься, плюс дать время поискать замену тебе. Для этого закон предусматривает 2 недели.
> меня в конторе держат как раба
Ты сам на такие условия согласился. Это не повод убежать все и бросить.
>>403770
http://ideone.com/SOgHcx — отдельно стоящий минус считается словом.
> Ведь чем сидеть дома сычевать, лучше на собеседовании насосаться и прийти прогуглить от баттхерта вопросы на котороых засыпался и начать учить что-то новое сразу, да?
Это может быть полезный опыт.
На таблице comments почему нет внешних ключей?
http://denis.in.ua/foreign-keys-in-mysql.htm
Было бы неплохо тебе как-нибудь потом порешать наши задачки на MySQL, про лайки и про кинотеатр, я чувствую, у тебя в SQL пробелы есть в знаниях.
—предупреждение что сначала надо пройти Путь HTML/CSS
— Основы JS: задачи на замыкания, работу с аргументами, this
— Основы JS: работа с коллекциями — map/filter/pluck/count
— Основы JS: deep copy
— lodash: пара задач типа найти самый населенный город
— ООП, прототипы и наследование: пара задачек вроде гамбургера
— DOM: add/removeClass
— DOM: поле с клетками
— DOM: сапер
— DOM: поиск в DOM
— DOM: что-нибудь на размеры/положение элемента
— jQuery: извлечение информации из страницы
— jQuery: плагин с крестиком для очистки поля
— jQuery: фильтр списка/таблицы + оптимизация
— jQuery: плагин excel
— jQuery UI: что-нибудь на автокомплиты
— jQuery UI: галерея картинок
— Knockout: какая-нибудь форма
— Backbone: роутинг, history API, MVC, синхронизация изменений, оптимизация синхронизации, валидация форм
— ???
Вот как-то так пока он выглядит. Ничего не забыл? Ангулар? не знаю, может потом и добавлю в самый конец. Node.JS? это вроде не фронтенд.
—предупреждение что сначала надо пройти Путь HTML/CSS
— Основы JS: задачи на замыкания, работу с аргументами, this
— Основы JS: работа с коллекциями — map/filter/pluck/count
— Основы JS: deep copy
— lodash: пара задач типа найти самый населенный город
— ООП, прототипы и наследование: пара задачек вроде гамбургера
— DOM: add/removeClass
— DOM: поле с клетками
— DOM: сапер
— DOM: поиск в DOM
— DOM: что-нибудь на размеры/положение элемента
— jQuery: извлечение информации из страницы
— jQuery: плагин с крестиком для очистки поля
— jQuery: фильтр списка/таблицы + оптимизация
— jQuery: плагин excel
— jQuery UI: что-нибудь на автокомплиты
— jQuery UI: галерея картинок
— Knockout: какая-нибудь форма
— Backbone: роутинг, history API, MVC, синхронизация изменений, оптимизация синхронизации, валидация форм
— ???
Вот как-то так пока он выглядит. Ничего не забыл? Ангулар? не знаю, может потом и добавлю в самый конец. Node.JS? это вроде не фронтенд.
Там тоже токенайзер и парсер в дерево, как я и говорил.
И есть такое: https://github.com/mr-mig/ru-it-chats/
Сам я там не сижу, так что насчет ценности не знаю.
Нате вам.
https://vk.com/doc43305699_337624855?hash=6c501cde4f524be89c&dl=a1c8364b60216c48ae
XAMPP и DenWER не предлагать, реквестую 5.5+ версию PHP и подходящий ему Apache.
Желательно с ссылками.
Для чего? Для того, чтобы мы друг друга снабжали годными идеями и постоянно делились чем то друг с другом и т.д.
Также не откажусь быть джуном у какого-нибудь синьжора, не откажусь от конфочки.
В общем рассмотрю все варианты.
О себе - 20 лет мало опыта, не очень много знаний, не бородат и т.д.
Вот мой vk.com/id236200246
Вот мой почтамп leaptoo@gmail.com
Фу блять, фуфло какое-то, какие, нахуй, еще опросники?
Русня ссаная, на инглише, ёб твою мать.
$a= 345;
$b= "+" (или -, или , или /)
$c= 679;
Можно как-то без if добавить, отнять эти числа?
Еще хуже... Короче, есть строка $a='123+677'; надо ее выполнить, пробовал через eval(), но что-то не получилось
C:\Users\CCCP>php -r "$a=2;$b='-';$c=1;$result=0;$str='$result=$a'.$b.'$c;';eval($str);echo $result;"
1
Спасибо, а можно как-то подобное сделать для $a='2-1'; не разбивая их регуляркой?
Спасибо большое, хочу написать чатбот который умеет чуть больше чем просто болтать
Выглядит просто, еслиб я был знаком с фреймворками, прям щас бы сделал наверное.
Добавил бы, но блядь, меня пугает твой пикрелейтед.
Все верно
все правильно теперь
Можно убрать переменные self и context, зачем они нужны?
>>Я обновил задание, поменяв порядок аргументов (почему? потому что так в lodash сделано).
> Какая разница?
Разница что теперь функция filter принимает аргументы в том же порядке что и ее аналог из lodash.
Верно
>>думаю почему это быдлокод, объяснять не надо?
> Объясни пожалуйста
Потому что этот код при преобразовании в CSS раскрывается в правила:
body .header div { margin: 4px; }
body .header div li { margin: 3px; }
body .header div li a { color: red; }
И в общем-то уже видно, что он некачественный.
Селекторы слишком длинные и довольно бессмысленные. Верстальщик просто скопировал структуру страницы, не пытаясь даже чуть-чуть подумать головой (возможно он даже не руками это делал, а чем-то сгенерировал).
Например, какой смысл имеет селектор «любой div внутри .header»? Почему div? Почему только внутри .header? Почему только внутри body? Он делает верстку ненадежной, так как стоит добавить внутрь header блок, содержащий div, как к нему применится этот стиль. Или наоборот, стоит вынести список из header как все стили с него отвалятся.
Я не могу представить ситуацию, где было бы правильно использовать селектор типа div или span.
В такой код тяжело вносить изменения. И искать причину ошибок тоже нелегко так как отладчик в браузере тебе покажет CSS, а не LESS правила.
Селекторы должны иметь смысл, например:
.menu - блок меню (независимо от того где оно находится)
.menu.header-menu (версия меню для шапки)
.menu > li — пункт меню верхнего уровня (обрати внимание на > )
.menu li — любой пункт меню
и т.д.
Вот хорошая статья на тему правильного составления селекторов: https://ru.bem.info/method/definitions/
Обрати внимание, там как раз затрагиваются вопросы «что если мы хотим перенести блок из шапки в подвал». С примером кода выше это равносильно переписыванию половины кода.
Заметь также, я не говорю что LESS — это плохо. LESS это неплохой инструмент. Но он никак не поможет тому, кто не разбирается в CSS. И если он добавляется в проект чтобы писать такие бессмысленные горы кода, то лучше бы его не использовали вообще.
>>думаю почему это быдлокод, объяснять не надо?
> Объясни пожалуйста
Потому что этот код при преобразовании в CSS раскрывается в правила:
body .header div { margin: 4px; }
body .header div li { margin: 3px; }
body .header div li a { color: red; }
И в общем-то уже видно, что он некачественный.
Селекторы слишком длинные и довольно бессмысленные. Верстальщик просто скопировал структуру страницы, не пытаясь даже чуть-чуть подумать головой (возможно он даже не руками это делал, а чем-то сгенерировал).
Например, какой смысл имеет селектор «любой div внутри .header»? Почему div? Почему только внутри .header? Почему только внутри body? Он делает верстку ненадежной, так как стоит добавить внутрь header блок, содержащий div, как к нему применится этот стиль. Или наоборот, стоит вынести список из header как все стили с него отвалятся.
Я не могу представить ситуацию, где было бы правильно использовать селектор типа div или span.
В такой код тяжело вносить изменения. И искать причину ошибок тоже нелегко так как отладчик в браузере тебе покажет CSS, а не LESS правила.
Селекторы должны иметь смысл, например:
.menu - блок меню (независимо от того где оно находится)
.menu.header-menu (версия меню для шапки)
.menu > li — пункт меню верхнего уровня (обрати внимание на > )
.menu li — любой пункт меню
и т.д.
Вот хорошая статья на тему правильного составления селекторов: https://ru.bem.info/method/definitions/
Обрати внимание, там как раз затрагиваются вопросы «что если мы хотим перенести блок из шапки в подвал». С примером кода выше это равносильно переписыванию половины кода.
Заметь также, я не говорю что LESS — это плохо. LESS это неплохой инструмент. Но он никак не поможет тому, кто не разбирается в CSS. И если он добавляется в проект чтобы писать такие бессмысленные горы кода, то лучше бы его не использовали вообще.
Дайджест новостей из мира PHP на хабре: http://habrahabr.ru/company/zfort/
(всем советую)
>>403910
Скорее у тебя не проблемы с логикой, а ты берешься сразу за что-то сложное, пропуская основы, и оттого путаешься. Лучше начинать с простых вещей.
Ну и если что, всегда можно попросить подсказку. Хотя она тебе скорее всего и не понадобится.
>>403929
Ну как сказать. Я конечно не знаю, врожденные логические способности или нет, но могу привести такой пример.
Вот я беру какую-то олимпиадную задачку сложного уровня, сижу с ней несколько часов, пробую разные варианты и не нахожу решения. Это значит, у меня нет логических способностей и мне никогда ее не решить?
Не думаю. Это значит что я вместо того, чтобы порешать сначала более простые задачки, почитать разборы других задач и теорию сразу берусь за сложное. И олимпиадники, которые их решают, они их решают за счет того, что они постоянно тренируются, а не только за счет каких-то врожденных способностей. Я сам был на занятиях, где их готовят, так что знаю.
А если брать задачи, которые решает программист, они гораздо проще и их решению уж точно можно научиться.
Да, ОП говорит. Пости свои решения задачек, я тебе поясню где что неправильно, что тебе стоит почитать и что переделать. Также, я много придираюсь к оформлению кода, имей в виду.
>>403953
> у меня багет от фронта. КОКОКО СДВИНЬ НА ПИКСЕЛ ВЛЕВО
Ты просто CSS наверно плохо знаешь и вместо того чтобы вдумчиво писать код, ставишь свойства наугад. Конечно, так ты ничего не добьешься.
Печально конечно, что в наше время людей, толком не знающих CSS, берут на работу. Лучше бы взяли способного студента какого-нибудь в стажеры.
>>403954
> он не может найти директорию для модуля, хотя адрес точно правильный.
Там может быть причина что ты не загрузил какую-то бибдиотеку (visual studio runtime) от майкрософт. Заметь, не Visual Studio, а runtime. Пиши больше подробностей,например что именно написано в сообщении, а то непонятно. Ну и заодно можешь свой httpd.conf и php.ini запостить.
Вот еще список вопросов поустановке — может там ответ найдется?
https://gist.github.com/codedokode/10774100
https://gist.github.com/codedokode/7054af4a03865c4cc863
Алсо, зачем именно 5.3? Это же старье.
Да, ОП говорит. Пости свои решения задачек, я тебе поясню где что неправильно, что тебе стоит почитать и что переделать. Также, я много придираюсь к оформлению кода, имей в виду.
>>403953
> у меня багет от фронта. КОКОКО СДВИНЬ НА ПИКСЕЛ ВЛЕВО
Ты просто CSS наверно плохо знаешь и вместо того чтобы вдумчиво писать код, ставишь свойства наугад. Конечно, так ты ничего не добьешься.
Печально конечно, что в наше время людей, толком не знающих CSS, берут на работу. Лучше бы взяли способного студента какого-нибудь в стажеры.
>>403954
> он не может найти директорию для модуля, хотя адрес точно правильный.
Там может быть причина что ты не загрузил какую-то бибдиотеку (visual studio runtime) от майкрософт. Заметь, не Visual Studio, а runtime. Пиши больше подробностей,например что именно написано в сообщении, а то непонятно. Ну и заодно можешь свой httpd.conf и php.ini запостить.
Вот еще список вопросов поустановке — может там ответ найдется?
https://gist.github.com/codedokode/10774100
https://gist.github.com/codedokode/7054af4a03865c4cc863
Алсо, зачем именно 5.3? Это же старье.
> Вообще по дефолту требование, сейчас большинство просит ие8+
В чем проблема? ИЕ8 почти полноценно поддерживает CSS2.1. Я например под ИЕ6/7 верстал, и после них ИЕ8 как Хром. Просто ты наверно не изучал толком CSS, а перепрыгивал темы и пропускал важные вещи.
>>403984
> вот наложение сеансов
В принципе, верно сделано.
> JOIN `film` AS `f1` ON `s1`.`film_id`=`f1`.`film_id`
Кстати, если поле называется одинаково, можно писать короче:
FROM t1 JOIN t2 ON (film_id)
Алсо, зачем ты отступ деалешь перед круглой скобкой? Странно же смотрится.
>>403983
> И со строчкой итого ещё не разобрался
ну давай, разбирайся, тогда и проверим.
> `name` VARCHAR(255) NOT NULL DEFAULT "Аноним",
Лучше для анонимов писать туда NULL или пустую строку и подменять его при выводе. Иначе у тебя нельзя отличить человека не заполнившего имя, от человека подписавшегося «Аноним».
> `text` TEXT NOT NULL,
По моему в поле TEXT NULL всегда разрешен, не? Погугли-ка сам.
Читать файл конфига надо в index.php, а не в Database. Причем желательно сделать не выбор «или config или config.local», а «confog.local подключается после config» чтобы можно было переопределить только часть настроек.
Чтобы не добавлять appName много раз, ты мог бы глобально добавить его один раз во view, посмотри, там есть такой (не описанный в доках) метод: https://github.com/codeguy/Slim/blob/master/Slim/View.php#L101 (а потом посмотри как data используется в render( ))
> https://github.com/sqghub/uppu.ru/blob/master/index.php#L42
Тут лучше поставить return после notFound (хотя по моему он и так выходит из функции) и убрать else
В добавлении комментариев нет никаких проверок типа непустой ли текст.
namespace в конфиге не нужен так как там нет функций, классов, констант.
> https://github.com/sqghub/uppu.ru/blob/master/model/CommentMapper.php#L13
Это плохо смотрится. В данном случае можно просто передавать NULL если родительский комментарий отсутсвует, и пустую строку для пустого имени.
Но если тебе надо будет где-то (в среднем или большом приложении) конструировать запросы по частям, то можно использовать паттерн Query Builder. Посмотри, например как он реализован в ZF: http://framework.zend.com/manual/1.12/ru/zend.db.select.html
В данном случае он не требуется.
> FROM `{$this->dataBase->getCommentsTableName( )}`
А в чем выгода выносить имя таблицы? Не очень понял. И если уж выносить то почему в класс dataBase, а не CommentMapper?
> $dbComment['fileId'] = $dbComment['file_id'];
Не проще тут использовать $comment->setFileId( $dbComment['file_id']) ? Вместо чехарды с массивом?
> clone $comment;
Что за странный код? Почему не new? Ты явно что-то делаешь не так.
Вообще, создание объекта из строки БД надо вынести в отдельную функицю.
> function searchInComments(&$comment, &$array)
Кошмар. Попробуй 2 раза вызвать функцию getCommentsByFileId — вылетит ошибка.
Также, код функции getCommentsByFileId слишком длинный и запутанный. Упрости его до 10 или меньше строк. Также, я думаю, надо избавиться от всех операторов clone ибо они явно там лишние. Зачем клонировать комментарии? Тебе надо 2 одинаковых комментария? Не надо.
> public function getCommentFromPost($post)
нужен тайп хинт
> `name` VARCHAR(255) NOT NULL DEFAULT "Аноним",
Лучше для анонимов писать туда NULL или пустую строку и подменять его при выводе. Иначе у тебя нельзя отличить человека не заполнившего имя, от человека подписавшегося «Аноним».
> `text` TEXT NOT NULL,
По моему в поле TEXT NULL всегда разрешен, не? Погугли-ка сам.
Читать файл конфига надо в index.php, а не в Database. Причем желательно сделать не выбор «или config или config.local», а «confog.local подключается после config» чтобы можно было переопределить только часть настроек.
Чтобы не добавлять appName много раз, ты мог бы глобально добавить его один раз во view, посмотри, там есть такой (не описанный в доках) метод: https://github.com/codeguy/Slim/blob/master/Slim/View.php#L101 (а потом посмотри как data используется в render( ))
> https://github.com/sqghub/uppu.ru/blob/master/index.php#L42
Тут лучше поставить return после notFound (хотя по моему он и так выходит из функции) и убрать else
В добавлении комментариев нет никаких проверок типа непустой ли текст.
namespace в конфиге не нужен так как там нет функций, классов, констант.
> https://github.com/sqghub/uppu.ru/blob/master/model/CommentMapper.php#L13
Это плохо смотрится. В данном случае можно просто передавать NULL если родительский комментарий отсутсвует, и пустую строку для пустого имени.
Но если тебе надо будет где-то (в среднем или большом приложении) конструировать запросы по частям, то можно использовать паттерн Query Builder. Посмотри, например как он реализован в ZF: http://framework.zend.com/manual/1.12/ru/zend.db.select.html
В данном случае он не требуется.
> FROM `{$this->dataBase->getCommentsTableName( )}`
А в чем выгода выносить имя таблицы? Не очень понял. И если уж выносить то почему в класс dataBase, а не CommentMapper?
> $dbComment['fileId'] = $dbComment['file_id'];
Не проще тут использовать $comment->setFileId( $dbComment['file_id']) ? Вместо чехарды с массивом?
> clone $comment;
Что за странный код? Почему не new? Ты явно что-то делаешь не так.
Вообще, создание объекта из строки БД надо вынести в отдельную функицю.
> function searchInComments(&$comment, &$array)
Кошмар. Попробуй 2 раза вызвать функцию getCommentsByFileId — вылетит ошибка.
Также, код функции getCommentsByFileId слишком длинный и запутанный. Упрости его до 10 или меньше строк. Также, я думаю, надо избавиться от всех операторов clone ибо они явно там лишние. Зачем клонировать комментарии? Тебе надо 2 одинаковых комментария? Не надо.
> public function getCommentFromPost($post)
нужен тайп хинт
https://www.elance.com/job/64559521/proposals
Кроме шуток. Не могу найти кодера, одни пилильщики вордпрессов повсюду. ЗДЕСЬ ЕСТЬ ТАКИЕ, я знаю.
> https://github.com/sqghub/uppu.ru/blob/master/model/FileMapper.php
> public function save(File $file)
Тут надо перевернуть ифы и сократить функцию до 10-15 строк.
> mkdir("userFiles/".($file->getId()), 0, true);
Исплоьзовать относительные пути ненадежно так как твой код зависит от того какой каталог рабочий. Надо использовать полный путь, чтобы все было надежно.
> public function saveAudioData(File $file)
Класс FileMapper занимается сохранением/загрузкой файлов из БД. Распознавать свойства аудиофайла не его задача.
Работу с медиаданными надо вынести в отдельный класс. Этот класс не должен никак взаимодействовать с БД, мне кажется, чтобы каждый занимался своим делом.
Удобно наверно сделать класс так:
для загружаемого файла:
$mediaData = MediaInfo::fromFile($file->getpath());
$file->setMediaInfo($mediaData);
для загружаемого из БД:
$mediaData = MediaInfo::fromArray($savedData);
$file->setMediaInfo($mediaData);
То есть у объекта File делаем поле, в котором может храниться объект MediaInfo. Ну или подумай. может можно лучше сделать. Заметь что в предложенном варианте MediaInfo не зависит ни от базы данных ни от класса File. Также, не нужен будет отдельный запрос UPDATE.
> https://github.com/sqghub/uppu.ru/blob/master/model/FileMapper.php#L72
А вот смотри, понадобится нам в списке файлов выводить пометку допустим, какого он типа. Что ты будешь делать? Может лучше тут делать массив не массивов, а объектов File?
>$file->setSize((string)(int)($post['size']/1024)." кб");
Плохая идея хранить размер текстом. А если надо найти все файлы от 100 до 1500 кб ты как их искать будешь? Храни нормализованные данные.
> https://github.com/sqghub/uppu.ru/blob/master/templates/download.php#L12
В шаблонах не используют функции. Можешь вынести повторяющийся код в отдельный шаблон (это обычно называется partial).
Ну и насчет комментариев, мне конечно не очень нравится вся эта чезарда с сложной сортировкой комментов. Проще наверно использовать Materialized Path, он позволяет выбирать данные из базы уже в нужном порядке. Плюс другие вещи вроде загрузки отдельной ветки комментариев.
> https://github.com/sqghub/uppu.ru/blob/master/model/FileMapper.php
> public function save(File $file)
Тут надо перевернуть ифы и сократить функцию до 10-15 строк.
> mkdir("userFiles/".($file->getId()), 0, true);
Исплоьзовать относительные пути ненадежно так как твой код зависит от того какой каталог рабочий. Надо использовать полный путь, чтобы все было надежно.
> public function saveAudioData(File $file)
Класс FileMapper занимается сохранением/загрузкой файлов из БД. Распознавать свойства аудиофайла не его задача.
Работу с медиаданными надо вынести в отдельный класс. Этот класс не должен никак взаимодействовать с БД, мне кажется, чтобы каждый занимался своим делом.
Удобно наверно сделать класс так:
для загружаемого файла:
$mediaData = MediaInfo::fromFile($file->getpath());
$file->setMediaInfo($mediaData);
для загружаемого из БД:
$mediaData = MediaInfo::fromArray($savedData);
$file->setMediaInfo($mediaData);
То есть у объекта File делаем поле, в котором может храниться объект MediaInfo. Ну или подумай. может можно лучше сделать. Заметь что в предложенном варианте MediaInfo не зависит ни от базы данных ни от класса File. Также, не нужен будет отдельный запрос UPDATE.
> https://github.com/sqghub/uppu.ru/blob/master/model/FileMapper.php#L72
А вот смотри, понадобится нам в списке файлов выводить пометку допустим, какого он типа. Что ты будешь делать? Может лучше тут делать массив не массивов, а объектов File?
>$file->setSize((string)(int)($post['size']/1024)." кб");
Плохая идея хранить размер текстом. А если надо найти все файлы от 100 до 1500 кб ты как их искать будешь? Храни нормализованные данные.
> https://github.com/sqghub/uppu.ru/blob/master/templates/download.php#L12
В шаблонах не используют функции. Можешь вынести повторяющийся код в отдельный шаблон (это обычно называется partial).
Ну и насчет комментариев, мне конечно не очень нравится вся эта чезарда с сложной сортировкой комментов. Проще наверно использовать Materialized Path, он позволяет выбирать данные из базы уже в нужном порядке. Плюс другие вещи вроде загрузки отдельной ветки комментариев.
> ! $masString[-($i)])
У тебя же нет в массиве отрицательных ключей.
>>404217
Для комментариев обычно применяют Materialized Path, так как он позволяет загрузить отдельную ветку и сортирует комменты в нужном порядке. Также с ним легко определить глубину комментария или выбрать всех родителей сразу.
Ну и плюс. с Mpath ты можешь легко разбить комментарии на страницы по 50 штук и отображать постранично.
>>404224
Начинающим лучше стаивть руками:
https://gist.github.com/codedokode/7054af4a03865c4cc863
https://gist.github.com/codedokode/10774100
>>404251
> есть ли какие либо технологии, которые помогают дают охуенный буст по скорости разработки
Использование готовых библиотек. Использование более высокоуровневых фреймворков.
Например ORM вместо ручного написания запросов. Генератор админки вместо ручного написания. Knockout шаблоны вместо ручного развешивания кучи обработчиков на jQuery. Guzzle вместо возни с curl_setopt. Автоматизация всего что можно.
> Симфони - ёбаный кал обоссаного бомжа
Неосилятор?
> Вордпрес
я вообще не представляю, как можно на равных сравнивать вородепрсс, Yii и Симфони. Ты не путаешь ничего?
> ! $masString[-($i)])
У тебя же нет в массиве отрицательных ключей.
>>404217
Для комментариев обычно применяют Materialized Path, так как он позволяет загрузить отдельную ветку и сортирует комменты в нужном порядке. Также с ним легко определить глубину комментария или выбрать всех родителей сразу.
Ну и плюс. с Mpath ты можешь легко разбить комментарии на страницы по 50 штук и отображать постранично.
>>404224
Начинающим лучше стаивть руками:
https://gist.github.com/codedokode/7054af4a03865c4cc863
https://gist.github.com/codedokode/10774100
>>404251
> есть ли какие либо технологии, которые помогают дают охуенный буст по скорости разработки
Использование готовых библиотек. Использование более высокоуровневых фреймворков.
Например ORM вместо ручного написания запросов. Генератор админки вместо ручного написания. Knockout шаблоны вместо ручного развешивания кучи обработчиков на jQuery. Guzzle вместо возни с curl_setopt. Автоматизация всего что можно.
> Симфони - ёбаный кал обоссаного бомжа
Неосилятор?
> Вордпрес
я вообще не представляю, как можно на равных сравнивать вородепрсс, Yii и Симфони. Ты не путаешь ничего?
Написать графический фид, если вкратце.
eval is evil. Это плохая идея в общем.
>>404338
Это ? https://www.elance.com/j/graphic-ads-feed/64559521/
Написано так, что я вообще не понял что тебе надо. И английский хромает. Потому наверно профессионалы и проходят мимо.
Думаешь, они поняли что автор хотел? Для индуса 100 долларов = зарплата за полмесяца работы.
>Для комментариев обычно применяют Materialized Path
Там же какая-то беда будет со вставкой нового комментария. Придется рекурсивно искать айди всех родителей, чтобы построить путь, так?
Бтв, я переделал немного их. Теперь комментарии отдельно от карты.
А по 50 штук я со своей картой тоже смогу выводить. Только подправлю её немного.
> Придется рекурсивно искать айди всех родителей, чтобы построить путь, так?
Нет.
Выбираешь по id родителя его путь, например, 1.2.3.
Находишь ребенка с максимальным номером, большим 1.2.3 но меньшим 1.2.4 (допустим это будет 1.2.3.9) и соответственно получаешь что вставляемый ответ должен иметь путь 1.2.3.10
Запрос на выборку ребенка можно сделать быстрым и использующим индексы:
SELECT path WHERE parentId = родитель AND path < 1.2.4 AND path > 1.2.3 ORDER BY path DESC LIMIT 1
такой запрос при наличии индекса (parentId, path) или хотя бы (path) будет шагать по индексу снизу вверх и выполняется быстро. Первый запрос (получить path по id) еще элементарнее.
Быстрее вставка только в Adjacency List, но он многое не позволяет, например выбрать ветку или выбрать постранично комментарии, или получить всю цепочку родителей.
Хотя в Mpath есть свои подвохи, например как хранить path чтобы он не был слишком длинными. Также, переносы ветки, удаление детей, вставка детей в середину списка вызывают необходимость пересчитывать кучу path. Это плата за быструю сортированную выборку.
Ох, вот не разобрался ты как следует в методах хранения древовоидных данных, а полезно бы разбираться и знать преимущества/недостатки. Хотя, может для начинающего это и сложновато.
Если будешь делать Mpath, не вписывай код прямо в CommentMapper. Сделай его отдельным универсальным классом чтобы его можно было подключить к любой таблице.
Нет, не можешь. Ты будешь сначала выбирать все комментарии, потом их сортировать, потом откидывать, а это не очень хорошо с точки зрения нагрузки на БД, ради 50 комментариев выбирать 500.
Но вообще, конечно это тема обширная, хранение деревьев, тут много чего можно придумать.
Что именно не ясно? Давайте я распишу (даже картинки приложил там лол)
Английский хромает - согласен.
>Нет, не можешь.
Нет смогу.
>Ты будешь сначала выбирать все комментарии, потом их сортировать
Я буду брать по 50, а потом сортировать. Так же, как и с хранением пути.
И если хранить путь, то воссоздавать иерархию для вывода все равно придется - не выводить же их один под другим.
Я передумал, я не смогу.
>Например ORM вместо ручного написания запросов. Генератор админки вместо ручного написания.
О да, ОРМ и скафолдинг - неше всё. Про то чтобы в ручную писать круд для админки мы давно уже забыли. Генерируется всё, что только может быть згенерировано. Заказчик просит ососать видя такую скорость разработки, лол.
> Неосилятор?
symfony2 после Yii кажеться каким то ёбаным здоровенным нахуй не нужным говнищем. написал на нём полтора проджекта и дропнул нахуй.
> я вообще не представляю, как можно на равных сравнивать вородепрсс, Yii и Симфони. Ты не путаешь ничего?
Нет, анончик, не путаю ничего. Для меня это всё абсолютно равнозначные инструменты зарабатывания денег. Ибо простой магазин с уникальным дизайном и вкусными плюшечками 1 хуй делается за две недели, что на ВП, что на Yii со своими классами. Но только, когда я буду ковыряться в сраном функциональном говне водпресса, разработчики будут несколько сотен раз прокляты. А когда будем пидорасить на Yii - это будет няшная няшность.
> Knockout шаблоны вместо ручного развешивания кучи обработчиков на jQuery
Вот это очень интерестно, Анончик. Ибо жиквери-код действительно растёт как ёбаный сраный снежный сука ком. Ты имеешь виду knockoutjs? Дейстивтельно годная вещь? В чём его годнота?
> И если хранить путь, то воссоздавать иерархию для вывода все равно придется - не выводить же их один под другим.
Почему? Как раз так и можно делать, добавляя отступ = глубине комментария. Или если тебе надо вложенные дивы, можно сравнивать глубину текущего с предыдущим и добавлять нужное число тегов.
> В чём его годнота?
Это не универсальное решение на все случаи жизни, а библиотека реализующая байндинг то есть привязку значений из JS переменных к html коду, позволяющая отслеживать изменение переменных и обновлять DOM страницы. Условно, ты добавляешь в массив элемент, а на экране в таблице создается новая строка. Открой мануал и почитай? посмотри примеры, а потом подумай сколько лапши надо для этого же написать на jQuery.
Алсо, если ты делаешь один, то 4 месяца не так и много.
> Ибо жиквери-код действительно растёт как ёбаный сраный снежный сука ко
Это потому что у вас наверно нет сильного фронтендщика
А зачем такой изврат, если не секрет?
> если он уже есть проверяю размер, если не совпадает,
ТО есть если имя и размер совпадают то это тот же файл? Ты серьезно?
> то меняю название, как делать рандомные названия?
лучше всего каждый файл в свою папку класть
> ТО есть если имя и размер совпадают то это тот же файл? Ты серьезно?
Как проверять просвети меня тогда?
>Ох, вот не разобрался ты как следует в методах хранения древовоидных данных, а полезно бы разбираться и знать преимущества/недостатки. Хотя, может для начинающего это и сложновато.
Просто такие вещи на практике воспринимаются. Я вот боюсь делать функцию вставки комментария, для которой мне нужно сделать три запроса.
Ясно, спасибо, Анончик. Обязательно гляну. Алсо да - я пиздячу один и сразу 2 проджекта. И всё таки, 4 месяца - это ебически большой промежуток времени.
Файлообменник не должен отвергать файл, только потому-что уже есть файл с таким-же названием, это же очевидно.
>Запрос на выборку ребенка можно сделать быстрым и использующим индексы:
А если я просто посчитаю всех детей через
SELECT COUNT() WHERE parentId = родитель
и докину эту count+1 к пути родителя?
лол
ты споришь только с целью чтобы оспорить?
подумай сам
this.variable.field
в той программе должно быть единым словом, так как
this,variable,field
по отдельности не имеют смысла. что тебе даст информация о том что this используется 5 раз в тексте, а variable - 4? а this.variable.field - 2 раза, this.variable.huild - 3 - это другое дело
ты доёбываешься до пробелов вокруг равно, но тут полную хуйню устроил
с исключениями та же хуйня
ты же сейчас растишь толпу ПРОГРОМИСТОВ которые вместо ретурн фалс будут исключения кидать из каждого метода, и будет на программу у них десяток обработчиков исключений.
вот если у тебя идёт работа со строкой, и где-то внутри произошла хуйня. там нужны исключения, они прерывают работу и выбрасываются наверх до тех пор пока не поймаются. если не поймаются - значит программа должна быть остановлена - это логично.
исключение кидать вместо фолс - это полное говно и говнокод
>Исключения как раз были придуманы чтобы избавиться от уродливых return false/ if $result === false
я понял, ты не оп, ты тралируешь меня
Про regex он написал хорошо. Так-же он в треде помогает сильно (только не советую делать до конца все как он говорит, заебешься допиливать) А ракуешь тут скорее ты. Не хочешь читать онеме ОПа? Ну так зайди на пхп.нет, открой мануал, там все тоже самое.
>Это — хорошо .
2 слова
в чём проблема избавляться от знаков?
>Наша цель не посчитать число любых разделенных пробелами символов, а посчитать число слов.
я буду спорить также как и ты
op4chotogonit
сколько здесь слов?
наша цель не посчитать число кусков состоящих из букв, а посчитать число слов. это одно слово, но по способу который ты считаешь правильным - 2
>Ты просто CSS наверно плохо знаешь и вместо того чтобы вдумчиво писать код
ты просто не знаешь о чём говоришь
когда тебя просят поставить это туда без макетов, а потом им кажется что расстояние слишком маленькое, или слишком большое, и ты сидишь двигаешь этот блок и каждый раз комитишь изменения
Я всё на том же месте где и был(
Общее число и сумма легко. А как сгруппировать среднее не понимаю.
http://sqlfiddle.com/#!2/621c43/52
Вот в шизофрению ударился.
http://sqlfiddle.com/#!2/621c43/62
этот тред довольно быстрый
конфа по программированию - хуета, мне кажется
алсо, ты хуйнёй занимаешься
читай книги и документацию
ты в конфе будешь двачевать голосом, эффективности минимум
Глупо и безсмысленно. Всё верно.
По содержимому, побайтово. Как вариант, можно вычислить md5 хеш - у него вероятность коллизии очень низка и если хеши совпадают то это один файл. Ну или загрузить оба файла в память в строку и сравнить через == без хешей.
Это называется дедупликация — при загрузке того же файла мы просто ссылаемся на уже загруженный.
Чего лол то?
Реально по книгам не могу, пробовал, ничего не выходило дальше задачек и основ, на реальных примерах идёт лучше.
>это заявление как раз для пхп треда двача
Прости, но я вообще не пишу на пхп, я тут мимо из руби треда.
Как превратить ссылку вида
ex.com/index.php?параметр1=значение в ex.com/catalog
или
ex.com/index.php?параметр1=значение&параметр2=значение в ex.com/catalog/category
Гм, ничего сложного. Спасибо!
Глаза боятся, руки делают. Как же ты будешь большие проекты писать тогда?
Эта тема может быть сложной для новичка, я когда-то давно изучал эти методы и мне пришлось листок бумаги схемами изрисовать и код написать самому чтобы разобраться.
>>404410
Можно и так. Но тот запрос который я написал, наверно чуть быстрее так как он обходит одну строчку таблиы, а не всех деетй. Но ты можешь и через COUNT сделать (хотя лучше не через COUNT, а выбрать MAX(path) у детей — тогда в случае дырок в нумерации все равно будет все верно).
>>404412
Книги в шапке есть вообще-то.
>>404414
Не понимаю в чем выгода считать не слова, а пробелы между ними? Почему вместо того чтобы решить задачу самым простым и логичным способом, надо искать обходные пути?
То же и с исключениями? Почему вместо общепринятого очевидного способа надо изобретать какие-то return false? Для чего по твоему исключения в PHP сделаны?
Значит можно допилить регулярку. Твой способ сломается в большем числе случаев типа пропущенных пробелов после запятой. Почему бы тебе уже код не показать и не проверить?
>>404429
Используй транзакции. Не коммить изменения в БД пока не сделаешь все что надо.
>>404432
Есть не наша
> Аноны, кто-то хотел скайп чатик для программистов. Вот, держите, кто-то с хабра организует такие: http://habrahabr.ru/post/242683/ (php там правда нет пока)
> И есть такое: https://github.com/mr-mig/ru-it-chats/
> Сам я там не сижу, так что насчет ценности не знаю.
>мне пришлось листок бумаги схемами изрисовать и код написать
Рисовал я на задачке про весы.
>а выбрать MAX(path) у детей
Честно говоря, я просто не хочу разбирать строку. Ненавижу копаться в символах.
Кстати, я сделал с путем. Пойду покопаюсь в строках теперь.
С картинкой.
Может быть. Может быть все посты в треде принадлежат ОПу. Может ты и есть оп, откуда мне знать?
но если все посты принадлежат опу - то ты и есть оп
а что если мы - две личности опа, считаем себя индивидуальностями, а на самом деле сейчас оп лежит привязанный где-нибудь в психушке деревни задрищенск и воображает себя экспертом по пхп?
Сделал пути через max(path) и сделал сохранение тоже через транзакции.
>ИЕ8 почти полноценно поддерживает CSS2.1. Я например под ИЕ6/7 верстал, и после них ИЕ8 как Хром. Просто ты наверно не изучал толком CSS, а перепрыгивал темы и пропускал важные вещи.
ОП, ты толковый парень, но иногда тупишь, лол. Ты видимо меня неправильно понял. Моя реплика имела целью донести тот факт, что ие8 это хорошо и нормально, и негодование того анона по поводу кнопки в ие8 неправильно.
Запостить код который уже написал (если он есть) и написать что именно непонятно, а что ты можешь и сам сделать. ОП или кто-нибудь еще даст подсказку.
http://ideone.com/smrB6A
К примеру. Оно и должно так сложно выглядить или способы проще есть?
Да, можно сделать проще за счет квантификаторов, то есть конструкций, задающих повторение:
звездочка ? + {N,} {N,M} {K}
Вот пример выражения для поиска почтовых индексов из 6 цифр:
/\\d{6}/
Также, надо проверить твой код на большом числе телефонов.
Задачу про номера телефонов надо проверить на большом числе телефонов, чтобы убедиться что твой код правильный. Но руками подставлять номера — долго и скучно. Пусть работает робот, а не человек! Давай-ка научимся основам автоматического тестирования и заставим железяку проверять саму себя.
Для этого давай добавим в программу тесты, чтобы сразу было видно, верно все работает или нет. Сделай 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' // нет +
);
Да, можно сделать проще за счет квантификаторов, то есть конструкций, задающих повторение:
звездочка ? + {N,} {N,M} {K}
Вот пример выражения для поиска почтовых индексов из 6 цифр:
/\\d{6}/
Также, надо проверить твой код на большом числе телефонов.
Задачу про номера телефонов надо проверить на большом числе телефонов, чтобы убедиться что твой код правильный. Но руками подставлять номера — долго и скучно. Пусть работает робот, а не человек! Давай-ка научимся основам автоматического тестирования и заставим железяку проверять саму себя.
Для этого давай добавим в программу тесты, чтобы сразу было видно, верно все работает или нет. Сделай 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' // нет +
);
Вот: http://ideone.com/5047fR ,но последние три я не могу сделать. Пытаюсь сделать вот такую штуку, но она не хочет работать:
http://ideone.com/rWcarI
Поскольку сейчас работы у меня как таковой нет, я решил не стоять на месте и продолжить заниматься. Мы с тобой уже сделали //простуюРегистрацию//, и следующем шагом должно было быть изучение ООП. Мне понравилась задача на REST-service и сейчас я возьмусь за её выполнение. Как накалякаю свой код - выложу суда. Добра...
Спасибо. Дома разберусь
Как же сложно всегда начинать! Особенно на только что вышедшем фреймворке, по которому документации маловато. Официальная документация - это 75% непонятных слов. Просто читать его от корки до корки не вижу смысла. Никогда так не делал. В программировании теория усваивается только параллельно с практикой. Как мне быть? Не хочу чтобы изучение фреймворка продвигалось с черепашьей скоростью. Хочу освоить его и уже пиздовать на работу.
Привет! Ну можно порадоваться за тебя, что ты смог где-то найти работу, но вообще ООП, MVC, фреймворки надо изучать обязательно. Без них ты будешь очень ограничен в выборе и сможешь заниматься только самыми низкоквалифицированными задачами типа «натянуть верстку на движок».
По ООП у меня в учебнике есть задачи, советую решить все, включая кошки-мышки — она хорошо помогает увидеть ошибки в понимании ООП и исправить это.
После ООП ты сможешь перейти к изучению фреймворков. Мы обычно даем сначала задачу сделать файлообменник на микрофреймворке Слим (если ты следишь за тредом то наверно видел ее, сейчас один анон ее делает), чтобы люди с простых вещей начинали и чтобы убедиться что человек основы понимает, а дальше можем изучать Юи и Симфони.
> Мне понравилась задача на REST-service и сейчас я возьмусь за её выполнение.
Хорошо, но без ООП там конечно так себе будет. Там же класс надо сделать.
> \{
Если добавить флаг -r то sed будет исплоьзовать чуть более новый диалект регулярок и бекслеш тут будет не нужен, детали в мануале.
Телефон 8888 1234567 праивльный — не распознает
Телефон 84951234567 правильный — не распознает
Пройдись по списку правильных/неправильных телефонов и проверь программу — она явно не работает.
Также, программа никак не выводит что телефон неправильный. по моему не очень удобно.
Также, подозреваю, хватило бы одного вызова sed так как он умеет фильтровать строки:
sed -r -n '/^[0-9]/p'
выведет только начинающиеся с цифр строки
Боюсь до мудрого старичка с твоего пика тебе пока далековато. Читай мануалы.
Ну давай разберем по частям тобою написанное.
> [()+"\\s-]{0,4}[0-9][()+"\\s-]{0,4}[0-9]
Это копирование одного и того же куска несколько раз. Его надо заменить на повторение, посмотри примеры с символами звездочка, плюс, , вопрос, {N,M} в уроке и в мануале:
http://php.net/manual/ru/regexp.reference.repetition.php
> (8|+7)
Символ + в регулярках имеет специальное значение, он задает число повторений. Он должен идти после скобок или символа, который повторяется.
Если ты хотел сказать «ищи знак плюс» надо писать либо \\+ либо [+]
В конце урока про регулярки это есть, перечитай пожалуйста еще раз.
Он выдает всех кто из России, Омска
Пробовал в sql запросе писать
>WHERE country = '$country' AND city = '$city'
Но что-то не так все равно. Потому что если одна из них пустая, выводит или ничего, или вообще все. А если переменных больше 2, так вообще ничего не работает.
> Официальная документация - это 75% непонятных слов.
Это значит что ты берешься сразу за сложное, пропуская простое. Я тебе советую лучше задавать вопросы, если что-то непонятно, например «что значит X» или «почему они пишут A а не B». Я либо поясню либо скажу какую тему гуглить.
Ну и если это первый фреймворк, то да, поначалу может быть трудно.
И не бойся в исходники заглядывать. Это сложно поначалу, но полезно.
> В программировании теория усваивается только параллельно с практикой.
Праивльно
> Как мне быть?
делать какое-то приложение на фреймворке, стараясь задействовать максимум его возможностей, плагинов и тд.
>>404514
>>404513
А почему русские буквы не работают? tr не поддерживает многобайтные символы в utf-8? Я проверил, действительно так. Ну значит ищи другой вариант, например sed или еще что-нибудь.
Вот тут http://lists.gnu.org/archive/html/bug-coreutils/2013-01/msg00022.html пишут в стиле «да, баг»
Боюсь, без полноценной поддержки utf-8 это нерабочее решение и лучше на php написать. Или найти поддерживающую utf-8 утилиту. Если ты линуксоид, ты должен знать решение.
sed вроде работает даже с поддержкой флага i:
$ locale
LANG=en_US.UTF-8
....
$ echo "Привет 手間どる" | sed 's/п/a/i'
aривет 手間どる
Только вот Putty почему-то кандзи выводит с конской разрядкой (большие промежутки между символами).
Ты можешь кстати использовать sed c флагом -n и p в регулярке чтобы отфильтровать лишние символы вместо tr. Только протестируй что он не ломает utf-8 символы.
— InnoDB поддерживает транзакции и внешние ключи. Как без них работать?
— InnoDB блокирует при записи отдельные строки, а MyISAM всю таблицу. Из-за этого в многопоточных (то есть нагруженный сайт к примеру) приложениях MyISAM тормозит. У InnoDB c этим в разы лучше, но можно получить замечательную ошибку deadlock detected. Please restart transaction.
— InnoDB использует надежную систему сохранения данных с логом. То есть прежде чем поменять что-то в таблице, данные пишутся в лог. MyISAM меняет данные как я понял, наживую. Если база упадет или сервер отключится в процессе записи, таблицы восстановвятся. С MyISAM можно получить битую таблицу.
Больше различий: http://rtfm.co.ua/mysql-otlichiya-mezhdu-myisam-i-innodb/
Я там вообще ни одной причины в пользу MyISAM не вижу.
Чтобы полностью понимать различия, надо знать про работу БД, storage engine, как обеспечивается поддержка транзакций и надежность.
Алсо таблица чуть устарела так как в новом MySQL полнотекстовый поиск есть в обоих движках.
Мне кажется, тут ты не прав.
Ты (и может кто-то еще) может подумать что у нас тут уроки уровня /b, а вот в видеокурсах с рутрекера совсем другой уровень. Я не думаю так. Сейчас в вебе практически все инструменты, фреймворки, библиотеки, мануалы общедоступны (если ты знаешь английский) и ты можешь использовать те же инструменты что и профессионалы.
Наоборот, книги и видеокурсы сильно устаревают, плюс много неграмотных и старых книг. В шапке ОП-поста указаны 2 неплохих, хотя староватых, книги.
Если у вас хватит сил и терпения, мы можем дойти до изучения любых связанных с вебом тем, включая сложные фреймворки типа Симфони, автоматизированное тестирование, single page apps, нагруженные приложения и прочее. Правда, аноны после освоения Слима, кто работу находит, кто ленится дальше изучать. Так что все от вас самих зависит.
С другой стороны ты же не забесплатно двигаешь, тебе это время оплачивают, верно? Считай это отдыхом от более сложных заданий.
>>404428
> А как сгруппировать среднее не понимаю.
Среднее число посетителей за сеанс = общее число посетителей для фильма / число сеансов, нет?
> Unknown column 'show.film_id' in 'on clause':
Ты имя таблицы или колонки перепутал.
Алсо, можно писать JOIN table ON (field) в твоем случае.
Анон, тебя я проверю наверно ближе к вечеру.
Хорошо, что ты добавляешь новые фичи. ты продвигаешься довольно быстро для наичнающего на незнакомом фреймворке. Но увы. качество кода начинает ухудшаться.
Тебе там надо будет найти время на рефакторинг папки models.
Из FileMapper вынести все, что работает с медиаданными и getid3, в отдельный класс. save( ) чуть упростить. Класс работы с медиаданными никак не должен зависеть от таблицы files и хорошо бы чтобы его можно было при необходимости повторно использовать.
CommentMapper разбить на 2 класса: класс-маппер комментариев и универсальный класс для реализации Materialized Path, не связанный с комментариями. Чтобы если например тебе надо будет в другой таблице реализовать древовидные данные, ты без единой строчки копипасты подключил бы этот класс (а в идеале вообще сделать интерфейс чтобы можно было сделать несколько классов-алгоритмов вроде Nested Sets, Adjacency List и менять их. Но это наверно в этой задаче не требуется).
Для комментариев сделать какую-то валидацию.
Добавить в репозиторий пустую папку для хранения файлов + все нужные htaccess
Представь например завтра мы захотим разрешить в комментарии добавлять картинки и аудиофайлы. Хорошо бы чтобы это решалось подключением существующего класса, а не копипастингом кода работы с id3.
Анон, тебе надо срочно подтягивать знания, в том числе по SQL, так как по моему ты пока не умеешь работать с базами данных. Куча элементарных ошибок.
> Пробовал в sql запросе писать
>>WHERE country = '$country' AND city = '$city'
Обычно делают отдельные таблицы «страны» и «города» и хранят id. Хотя может это не ваш случай. Почитай про нормализацию:
http://club.shelek.ru/viewart.php?id=311
http://habrahabr.ru/post/129195/
> Потому что если одна из них пустая, выводит или ничего, или вообще все.
Так и должно быть. Условие WHERE city = '' ищет записи где вместо города пустая строка.
Также, не подставляй переменные в запрос, это путь к Sql инъекии и быдлокодинг, используй плейсхолдеры, например в PDO: http://habrahabr.ru/post/137664/
насчет вопроса «как лучше» зависит от нагрузки. Если данных мало и нагрузка небольшая то хватит возможностей MySQL. Если много или большая то внешние поисковые движки: sphinx, elastic search. Но тебе сначала надо базы данных подучить. У нас есть хорошие задачки и ссылки, если интересует: https://gist.github.com/codedokode/10539213
Вот информация про sphinx: https://gist.github.com/codedokode/10539366
>>404677
Молодец.
— Сайт phptherightway
— Дайджест новостей мира php на хабре: http://habrahabr.ru/company/zfort/
— Блоги больших компаний вроде badoo ( http://habrahabr.ru/company/badoo/ ), 2ГИС или yandex
— Сайт http://phptrends.com/ если надо найти библиотеку для чего-нибудь
>Правда, аноны после освоения Слима, кто работу находит..
Что, серьезно? Таких мелочей, что я сейчас изучаю (файлобменник), хватает, чтобы потом найти работу?
Так смотря какую. Да, находят, были несколько тредов назад кулстори, анон у нас учился и смог попасть в какую-то вебстудию.
Это не такая уж и мелочь. По идее, после того как ты решишь задачу на файлообменник, ты сможешь сам сделать простой сайтик. В некоторых компаниях это считается вполне достаточным для стажера/джуниора.
Я уже разобрался, спасибо
>save( ) чуть упростить
А что там упрощать? Там толком ничего и не делается. Взять файл, записать в бд, переместить.
Ифы перевернуть для начала. Что это за бардак — if размером на всю функцию? Сохранение в БД и сохранения файла в нужную папку имеет смысл разнести в 2 функции.
>Ифы перевернуть для начала.
Что это значит?
>if размером на всю функцию
А как еще? или можно просто иф (чтото) {return} и все?
>Сохранение в БД и сохранения файла в нужную папку имеет смысл разнести в 2 функции.
Так там и без того по три строчки же.
>>Ифы перевернуть для начала.
> Что это значит?
if (условие) {
50 строк;
} else {
2 строки;
}
заменяется на
if (не условие) {
2 строки;
return
}
50 строк;
Попробуй замени и посмотри насколько код аккуратнее станет от такой просто вещи.
> Так там и без того по три строчки же.
Критерием тут является не число строк, а то что это очень разные вещи, вставка в Бд и сохранение файла и удобнее их разнести. Тем более что завтра там может стать уже не 3 строчки.
У него какие-то были видимо. Там в файлообменнике например есть загрузка файлов перетаскиванием, тут без JS никак.
Так перемещение файла и создание директории - это уже встроенные функции.
$this->field->shareAnimals()[$i] вызывает ошибку unexpected '['
хотя я проверил на айдеоне, и так вроде бы можно делать http://ideone.com/vfwuD7
Пофиг, я уже по другому сделал.
http://ideone.com/MKrmcS
>ни одной причины в пользу MyISAM не вижу
частоменяющаяся таблица с логами, например.
иннодб будет расти до тех пор пока ты не охуеешь, она не уменьшает свой размер
у майисам этого нет
Это для 1.1. На 2.0 такие команды не запустятся. Я не понимаю сути ошибки. Появилась она после того, как я поудалял ненужные файли из папок controllers и view. Видимо недоудалил или переудалил
>>404658
> делать какое-то приложение на фреймворке, стараясь задействовать максимум его возможностей, плагинов и тд.
Хорошо. Попробуем начать. Я хочу сделать музыкальный сайт. Его я уже делал с нуля. Когда понял, что мне придется делать много повторений и что на моём уровне врядли это всё выйдет по уму, задумался об альтернативе
БД уже есть. Несколько таблиц со связями. Нужно сделать красивый и удобный интерфейс для работы с ними. Что посоветуете изучать конкретно? Какие есть удобные плагины не хочу изобретать велосипед, не зная о том, что его уже изобрели
P.S: Раздел мануала Первое Знакомство: Работа с базами данных прочитал. И даже смог повторить написанный код - заработало. Хотя как это работает еще плохо представляю
Нет, смотри как у тебя сделано:
функция сохранить файл {
10 строк вставить информацию в БД;
10 строк переместить файл на постоянное хранение;
}
Тут явно можно сделать 2 функции:
функция сохранить файл {
$this->insertFileInfoDb(....);
$this->storeUploadedFile(...);
}
Потому что сейчас у тебя там стена кода, выполняющего 2 вещи сразу.
Еще:
> } catch (\Exception $e) {
> $this->dataBase->rollBack( );
> echo "Ошибка: " . $e->getMessage( );
> return $result;
Во-первых, не выводи тут причину ошибки через echo. Какой смысл показывать пользователю непонятную техническую информацию? Для записи ошибок есть логи и функция error_log в PHP. Но тут они не нужны.
Во-вторых, это ошибочный код, так как если выбросится искючение, то переменная result так и не будет создана. Ты должен гарантированно ее создать до использования или же написать return внутри catch. Но этот тут тоже не нужно.
Ну и наконец не должен ловить все виды исключений, а только нужные тебе. Но опят же, тут это не надо.
Я думаю, try/catch тут вообще не нужен. То есть при возникновении исключения оно будет завершать скрипт (и из-за этого соединение с БД закроется и незакомиченная транзакция отменится сама собой). Прочитай мой мини-урок по исключениям: https://gist.github.com/codedokode/65d43ca5ac95c762bc1a так как я подозреваю, ты в них не разобрался.
Или же ты с какой-то целью ловишь исключение?
>>404775
До PHP 5.5 сразу после вызова функции нельзя ставить выбор из массива, надо использовать временную переменную (это связано с особенностями анализатора кода и исправлено в новых версиях)
Нет, смотри как у тебя сделано:
функция сохранить файл {
10 строк вставить информацию в БД;
10 строк переместить файл на постоянное хранение;
}
Тут явно можно сделать 2 функции:
функция сохранить файл {
$this->insertFileInfoDb(....);
$this->storeUploadedFile(...);
}
Потому что сейчас у тебя там стена кода, выполняющего 2 вещи сразу.
Еще:
> } catch (\Exception $e) {
> $this->dataBase->rollBack( );
> echo "Ошибка: " . $e->getMessage( );
> return $result;
Во-первых, не выводи тут причину ошибки через echo. Какой смысл показывать пользователю непонятную техническую информацию? Для записи ошибок есть логи и функция error_log в PHP. Но тут они не нужны.
Во-вторых, это ошибочный код, так как если выбросится искючение, то переменная result так и не будет создана. Ты должен гарантированно ее создать до использования или же написать return внутри catch. Но этот тут тоже не нужно.
Ну и наконец не должен ловить все виды исключений, а только нужные тебе. Но опят же, тут это не надо.
Я думаю, try/catch тут вообще не нужен. То есть при возникновении исключения оно будет завершать скрипт (и из-за этого соединение с БД закроется и незакомиченная транзакция отменится сама собой). Прочитай мой мини-урок по исключениям: https://gist.github.com/codedokode/65d43ca5ac95c762bc1a так как я подозреваю, ты в них не разобрался.
Или же ты с какой-то целью ловишь исключение?
>>404775
До PHP 5.5 сразу после вызова функции нельзя ставить выбор из массива, надо использовать временную переменную (это связано с особенностями анализатора кода и исправлено в новых версиях)
>Я думаю, try/catch тут вообще не нужен.
Ты сам выше говорил, что организовать перемещение файла и запись в базу надо через транзакции. Как еще?
А, и еще забыл. Надеюсь ты понимаешь, что начало транзакции и коммит должны в идеале находиться в одной функции (иначе сложно увидеть как это работает). Если ты будешь разбивать save на 2 функции, то в нее так же можно поставить эти команды beginTransaction, commit.
Кстати, в Симфони транзакции сделаны через анонимные функции (которые делают begin,commit, а также ловят исключения и отменяют транзакцию при его возникновении), выглядит это так:
$dbal->translactional(function ($dbal) {
... код внутри транзакции ....
});
Мануал на англ: http://doctrine-dbal.readthedocs.org/en/latest/reference/transactions.html
При таком подходе у тебя явно видно код, который заключен в транзакцию, и обеспечивается автоматическая отмена и коммит.
Если хочешь, можешь попробовать так же сделать в классе Database. Если не хочешь, можешь не делать.
Насчет мозгов, тут можно применить простой алгоритм:
Определяем все возможные ходы мышки, в том числе стоять на месте. Для каждого хода считаем число очков. Выбираем ход с максимальным числом очков.
Очки даются за расстояние от кошек (чем дальше тем больше), и за число вариантов хода (ход в угол дает меньше очков чем ход на центральную клеточку, так как в углу тебя могут легко зажать). Конкретные цифры надо придумать и сбалансировать. Ну и может ты еще какие-то критерии добавишь.
>Если хочешь, можешь попробовать так же сделать в классе Database. Если не хочешь, можешь не делать.
Хочу и сделаю позже. Заодно уточню, верно ли я понял идею.
> иннодб будет расти до тех пор пока ты не охуеешь, она не уменьшает свой размер
Во-первых для innodb удобнее включать «1 таблица = 1 файл», а не валить все в 1 файл. Во-вторых, в этом случае команда OPTIMIZE TABLE умеет сжимать таблицы: http://dev.mysql.com/doc/refman/5.1/en/optimize-table.html
Логично запускать ее сразу после того как ты подчищаешь логи. Но даже без OPTIMIZE, как я понимаю, блоки от удаленных записей могут использоваться для новых.
Алсо, я сам с таким не сталкивался. Интересная особенность.
>>404808
Скорее всего ты удалил SiteController. Если у тебя свой контроллер для ошибок то ты можешь его указать где-то в конфиге. А зачем ты удаляешь файлы? Ты скачивал не настоящий Юи, а сборку? В этом случае я советую так не делать, скачать ванильный фреймворк и ничего из него не удалять (и ничего в нем не править).
>>404808
Yii (2 или 1) или Симфони 2 + Доктрина. Имей в виду, что Симфони круче, но сложнее. В обоих есть стандартные средства или плагины для генерации админки.
Так транзакции это begin/rollback/commit/, а echo и try/catch зачем?
Если ты читал мой урок, там написано что throw и catch нет смысла писать в одной функции так как проще написать if в таком случае:
if (!(move_uploaded_file(...)) {
rollback(...);
return ...;
}
также, там написано что если ты создаешь свои исключения и ловишь их то надо создавать отдельный класс исключений. А то ты ловишь вообще все виды исключений.
>в этом случае команда OPTIMIZE TABLE умеет сжимать таблицы
nyet
http://dba.stackexchange.com/questions/24942/how-do-i-shrink-the-innodb-file-ibdata1-without-dumping-all-databases
нытьём завален весь стаковерфло
только ручной дроп спасает
Да, ты прав, спасибо за внимательность.
>>404780
> public function setField(GameField $field)
А когда ты удаляешь с поля животное, почему связь с полем не разрываешь?
> public function move
Если у тебя есть код
if (условие) {
50 строк
} else {
2 строки
}
То его надо попробовать перевернуть, чтобы было
if (не выполняется условие) {
2 строки
} else {
50 строк
}
А еще лучше
if (не выполняется условие) {
2 строки;
return;
}
50 строк;
> public function shareAnimals()
Что-то этот код плохо выглядит. Нужно больше инкапсуляции. Класс Поле должен не давать массив со словами «вот забирайте и делайте что хотите», а выполнять конкретные запросы вроде «найди всех мышей в таком-то радиусе».
> findClosestMouse
Вот это наверно лучше перенести в класс Поле.
> if ($this->x == $target['x'] && $this->y == $target['y']) {
Проверку на съедение лучше делать так:
животное = получить животное с координатами x, y;
если (это мышь) {
съесть;
удалить с карты;
} если (это другое животное) {
ошибка, выбрасываем исключение; // защищаемся от ошибок когда алгоритм пытается поставить 2 кошки на клетку
}
перемещаемся на клетку;
> public function killMouse($x, $y)
лучше сделать более общую функцию, удалить животное Животное с карты. Вдруг завтра мы захотим чтобы собака ела кошек.
Да, ты прав, спасибо за внимательность.
>>404780
> public function setField(GameField $field)
А когда ты удаляешь с поля животное, почему связь с полем не разрываешь?
> public function move
Если у тебя есть код
if (условие) {
50 строк
} else {
2 строки
}
То его надо попробовать перевернуть, чтобы было
if (не выполняется условие) {
2 строки
} else {
50 строк
}
А еще лучше
if (не выполняется условие) {
2 строки;
return;
}
50 строк;
> public function shareAnimals()
Что-то этот код плохо выглядит. Нужно больше инкапсуляции. Класс Поле должен не давать массив со словами «вот забирайте и делайте что хотите», а выполнять конкретные запросы вроде «найди всех мышей в таком-то радиусе».
> findClosestMouse
Вот это наверно лучше перенести в класс Поле.
> if ($this->x == $target['x'] && $this->y == $target['y']) {
Проверку на съедение лучше делать так:
животное = получить животное с координатами x, y;
если (это мышь) {
съесть;
удалить с карты;
} если (это другое животное) {
ошибка, выбрасываем исключение; // защищаемся от ошибок когда алгоритм пытается поставить 2 кошки на клетку
}
перемещаемся на клетку;
> public function killMouse($x, $y)
лучше сделать более общую функцию, удалить животное Животное с карты. Вдруг завтра мы захотим чтобы собака ела кошек.
>Так транзакции это begin/rollback/commit/, а echo и try/catch зачем?
Честно говоря, я скопировал откуда-то пример. Сейчас займусь.
>Да, ты прав, спасибо за внимательность.
ДА Я УМНЕЕ ЧЕМ ОП РАДИ ЭТОГО Я СИДЕЛ ИТТ 10 ТРЕДОВ СКРИН
Я же написал: надо не хранить все таблицы в одном большом файле, а каждую в своем, тогда OPTIMIZE работает.
>Вот это наверно лучше перенести в класс Поле.
Так ты вроде говорил, что кошка сама должна уметь искать ближайшую мышь.
Гм. Ну так она сама и ищет, вызывая методы объекта Поле. Ну можешь пока оставить так, хорошо.
Как-то так у меня выглядит метод базыд анных:
http://ideone.com/KuKQVD
И как-то так я его использую:
http://ideone.com/XZZvkd
Я верно понял?
> if (!$content)
Там по задумке content это функция, а ты ее не вызываешь.
Алсо, откатывать надо транзакцию в случае возникновения исключения (и затем перевыбрасывать исключение далее).
вот исходник из Doctrine DBAL: https://github.com/doctrine/dbal/blob/master/lib/Doctrine/DBAL/Connection.php#L1094
Doctrne DBAL - это класс для работы с БД на низком уровне, то есть счиатй улучшенный PDO. Он является отдельным проектом, но делается для Doctrine 2.
Doctrine 2 — это ORM-библиотека, которая может сохранять и загружать сущности из базы данных без необходимости писать мапперы вручную (но в этой задаче ты пока будешь писать все вручную чтобы научиться). Dcotrine поддерживает связи между сущностями, разные плагины (в том числе для хранения древовидных данных), транзакции и много чего еще.
Вот как например выглядит добавление комментария к файлу:
$em = $doctrine->getEntityManager( );
// загружаем файл с указанным id. Если мы его уже ранее загрузили в память то возвращается существующий объект
$file = $em->find('File', $id);
if (!$file) {
....
}
// загружаем родительский коммент
$parentComment = $em->find('Comment', $parentId);
$comment = new Comment( );
$comment->setName("Иван");
$comment->setText("Hello");
$comment->setParent($parentComment);
// в этот момент будут подгружены все комментарии к файлу и в список вставлен новый
$file->addComment($comment);
// передаем новый коммент под управление доктрины
$em->persist($comment);
// сохраняем все изменения, которые мы сделали в объектах, в базу. Что конкретно мы поменяли, указывать не надо, доктрина сама их найдет.
$em->flush( );
Но это так, чтобы ты понимал что такое доктрина, для задачи на файлообменник это слишком мощная библиотека.
> if (!$content)
Там по задумке content это функция, а ты ее не вызываешь.
Алсо, откатывать надо транзакцию в случае возникновения исключения (и затем перевыбрасывать исключение далее).
вот исходник из Doctrine DBAL: https://github.com/doctrine/dbal/blob/master/lib/Doctrine/DBAL/Connection.php#L1094
Doctrne DBAL - это класс для работы с БД на низком уровне, то есть счиатй улучшенный PDO. Он является отдельным проектом, но делается для Doctrine 2.
Doctrine 2 — это ORM-библиотека, которая может сохранять и загружать сущности из базы данных без необходимости писать мапперы вручную (но в этой задаче ты пока будешь писать все вручную чтобы научиться). Dcotrine поддерживает связи между сущностями, разные плагины (в том числе для хранения древовидных данных), транзакции и много чего еще.
Вот как например выглядит добавление комментария к файлу:
$em = $doctrine->getEntityManager( );
// загружаем файл с указанным id. Если мы его уже ранее загрузили в память то возвращается существующий объект
$file = $em->find('File', $id);
if (!$file) {
....
}
// загружаем родительский коммент
$parentComment = $em->find('Comment', $parentId);
$comment = new Comment( );
$comment->setName("Иван");
$comment->setText("Hello");
$comment->setParent($parentComment);
// в этот момент будут подгружены все комментарии к файлу и в список вставлен новый
$file->addComment($comment);
// передаем новый коммент под управление доктрины
$em->persist($comment);
// сохраняем все изменения, которые мы сделали в объектах, в базу. Что конкретно мы поменяли, указывать не надо, доктрина сама их найдет.
$em->flush( );
Но это так, чтобы ты понимал что такое доктрина, для задачи на файлообменник это слишком мощная библиотека.
Алсо, ты наверно не читал мой урок по исключениям. Ты сделал что функция возвращает false/true а у меня написано что исключения позволяют ничего не возвращать (и не проверять), а просто делать throw при ошибке.
Я читал, но по диагонали, так как не хотел тогда касаться исключений. Видимо, многого хотел.
Я думал, что рано.
Такой вопрос. Если я использую исключения, то мне нужны свои, чтобы не ловить все подряд. В перспективе у меня могут быть разные исключения (ну там у файлов одни, у комментариев другие).
Так вот: стоит ли мне сделать отдельный файл, в котором будут описаны нужные мне исключения? Или описывать их в среде применения?
Я понимаю. Но я думал, что исключения, кхм, могут быть исключением.
Там же всего ничего.
class MyException extends \Exception;
И все.
https://github.com/sqghub/uppu.ru
Но даже если с этим все, у меня есть множество сомнений по поводу Materialized Path. И, возможно, парочка вопросов.
Нет. Вот примеры кода из Doctrine DBAL: https://github.com/doctrine/dbal/tree/master/lib/Doctrine/DBAL/Exception
Ой, я просто торможу. Есть же пространства имен. Я такой глупый.
задавай
> $result['code'] = 1;
Используй константы, а не магические числа: https://ru.wikipedia.org/wiki/Магическое_число_(программирование)
> function () use ($file)
Тайп хинт нужен
> Ошибка сохранения файла. $e
Пользователь сайта не разбирается в программировании и ему неинтересны технические сообщения на английском. Если сообщения нужны тебе. пиши их в логи — в Слим встроен логгер (причем не абы какой, а соответствующий стандарту PSR на логгеры).
Непойманные исключения вроде бы пишутся сами по себе в лог Апача.
> throw new \Exception("Невозможно создать дирректорию"
Если ты собираешься перехватывать исключение то нужен свой класс. Если нет то необязательно.
> https://github.com/sqghub/uppu.ru/blob/master/model/CommentMapper.php#L8
Если класс DataBase является обязательным для работы маппера, удобнее передавать его через конструктор так как в этом случае невозможно забыть его передать.
> https://github.com/sqghub/uppu.ru/blob/master/model/CommentMapper.php#L17
Я думаю лучше сделать в DataBase более общий метод: insert($table, array $values), а в этой функции не мучаться с сборкой запроса. Но в данном случае может быть можно даже поступить проще: вместо того чтобы собирать запрос, всегда передавать все значения, просто указывать NULL или пустую строку для тех которые должны быть пустые. Для name и parentId у тебя ведь разрешен NULL в базе данынх? Тогда проблемы нет.
> SELECT FROM `{$this->dataBase->getCommentsTableName
Зачем вынести имя таблицы в другой класс?
> $query->setFetchMode(dataBase::FETCH_ASSOC);
По моему он по умолчанию такой и есть
> $comments["{$dbComment['id']}"] = clone $comment;
Тут явно должно быть сделано через new. Я не понимаю, зачем что-то клонировать.
> if (isset($comments)) {
> return $comments;
> } else {
> return null;
> }
Плохая идея когда функция возвращает разные типы данных. Ты не можешь с таким кодом написать
foreach ($x->getCommentsByFileId(...) as $comment)
И это плохо и надо исправить.
В фунгкции getCommentById все ок, там null возвращать можно.
> public function getCommentFromPost($post)
Поля в массиве могут и отстутствовать, это же от пользователя приходит. Алсо, нужен тайп хинт.
задавай
> $result['code'] = 1;
Используй константы, а не магические числа: https://ru.wikipedia.org/wiki/Магическое_число_(программирование)
> function () use ($file)
Тайп хинт нужен
> Ошибка сохранения файла. $e
Пользователь сайта не разбирается в программировании и ему неинтересны технические сообщения на английском. Если сообщения нужны тебе. пиши их в логи — в Слим встроен логгер (причем не абы какой, а соответствующий стандарту PSR на логгеры).
Непойманные исключения вроде бы пишутся сами по себе в лог Апача.
> throw new \Exception("Невозможно создать дирректорию"
Если ты собираешься перехватывать исключение то нужен свой класс. Если нет то необязательно.
> https://github.com/sqghub/uppu.ru/blob/master/model/CommentMapper.php#L8
Если класс DataBase является обязательным для работы маппера, удобнее передавать его через конструктор так как в этом случае невозможно забыть его передать.
> https://github.com/sqghub/uppu.ru/blob/master/model/CommentMapper.php#L17
Я думаю лучше сделать в DataBase более общий метод: insert($table, array $values), а в этой функции не мучаться с сборкой запроса. Но в данном случае может быть можно даже поступить проще: вместо того чтобы собирать запрос, всегда передавать все значения, просто указывать NULL или пустую строку для тех которые должны быть пустые. Для name и parentId у тебя ведь разрешен NULL в базе данынх? Тогда проблемы нет.
> SELECT FROM `{$this->dataBase->getCommentsTableName
Зачем вынести имя таблицы в другой класс?
> $query->setFetchMode(dataBase::FETCH_ASSOC);
По моему он по умолчанию такой и есть
> $comments["{$dbComment['id']}"] = clone $comment;
Тут явно должно быть сделано через new. Я не понимаю, зачем что-то клонировать.
> if (isset($comments)) {
> return $comments;
> } else {
> return null;
> }
Плохая идея когда функция возвращает разные типы данных. Ты не можешь с таким кодом написать
foreach ($x->getCommentsByFileId(...) as $comment)
И это плохо и надо исправить.
В фунгкции getCommentById все ок, там null возвращать можно.
> public function getCommentFromPost($post)
Поля в массиве могут и отстутствовать, это же от пользователя приходит. Алсо, нужен тайп хинт.
>Тайп хинт нужен
Так то уже переданная переменная, какой тайпхинт?
>Пользователь сайта не разбирается в программировании и ему неинтересны технические сообщения на английском. Если сообщения нужны тебе. пиши их в логи — в Слим встроен логгер (причем не абы какой, а соответствующий стандарту PSR на логгеры).
Я с логами позже разберусь.
>Если ты собираешься перехватывать исключение то нужен свой класс.
Дело в том, что я перехватываю там и свое, и от PDO.
>удобнее передавать его через конструктор
Это я не переделал обратно. У меня была какая-то ГЕНИАЛЬНАЯ идея, но она была неверно, а назад делать не стал.
>Зачем вынести имя таблицы в другой класс?
Так а вдруг ты их захочешь иначе назвать? Или это лишний геморрой?
>По моему он по умолчанию такой и есть
Просто взял из примера, да.
>Тут явно должно быть сделано через new. Я не понимаю, зачем что-то клонировать.
Ступил, исправил.
>И это плохо и надо исправить.
Сделаю позже.
>Поля в массиве могут и отстутствовать, это же от пользователя приходит.
Так они просто пустые придут, это учтено.
>Алсо, нужен тайп хинт.
А здесь-то какой?
Посчитай круглые скобки в строке 12
>>404884
> https://github.com/sqghub/uppu.ru/blob/master/model/CommentMapper.php#L80
> "`fileId`={$comment->getFileId()}"
Вот это очень плохо. Ты вставляешь данные прямо в SQL код вместо использования плейсхолдеров и передаешь куски SQL кода. Это скорее всего значит что функция спроектирована неверно.
Также, не очень правильно что ты задаешь Mpath в момент создания Comment из post-данных. Может ты его и не собирался никуда вставлять?
Мне кажется, это должно делаться при попытке сохранения. То есть ты задаешь parentId и вызываешь save для коммента и маппер в этот момент проставляет ему Mpath и после этого сохраняет.
Например в Doctrine, расширение для работы с деревом подписывается на событие вставки/удаления сущностей и соответственно при вставке/удалении меняет поля и делает нужные запросы.
Заметь что такая схема (маппер дерева вызывается перед и после сохранения и удаления сущностей) позволяет CommentMapper не знать о том какой тип дерева используется и менять их не переписывая код функции save.
> решение с $addCondition выглядит неудачным, но я не придумал, как еще обобщить
Есть такая идея: сделать «поля группировки», то есть ты можешь в маппере при создании указать по каким полям будет идти партицирование (разбиение на части):
$mpMapper->setPartitionBy(array('fileId'));
Соответственно mpMapper будет считать что в таблице не одно дерево, а N деревьев, у каждого свой fileId.
Либо же это можно передавать в конструктор чтобы не забыли.
Для универсальности, полей группировки может быть несколько (потому массив). решение с полями группировки удовлетворит 99% ситуаций, а для оставшегося 1% (когда надо группировать по хитрым условиям) в таблицу можно добавить дополнительное поле.
Дальше, мне кажется, имя таблицы надо передавать в конструктор MPMapper. Оно же не меняется в ходе работы.
Имена полей path, parent_id можно либо тоже передавать либо задать жестко.
Вот первый вариант, пришедший в голову:
$mpMapper = new MPMapper($db, 'comments', 'path', 'parent_id');
// генерирует путь для вставки в конец списка детей для данного файла и комментария
$path = $mpMapper->createPathForAppend($parentId, ['fileId' => $comment->getFileId()]);
$comment->setPath($path);
Соответственно $mpMapper знает имена полей и может сам сделать нужный запрос. В этом варианте MpMapper никак не взаимодействует с объектом Comment напрямую.
К сожалению при таком подходе полной абстракции от используемой системы хранения не получается так как CommentMapper должен содержать код работы с path и ты не можешь одним движением переделать его на использование Adjacency List или Nested Sets. Для этого надо поменять способ подключения маппера:
$mpMapper = new MPMapper($db, 'comments', 'path', 'parent_id');
$mpMapper->setPartitionBy(..);
$mpMapper->beforeInsert($comment); // маппер сам вычисляет путь и проставляет его в $comment
... вставляем сущность в БД ...
$comment->setId($id);
$mpMapper->afterInsert($comment); // вдруг он что-то хочет сделать после вставки
Здесь mpMapper должен сам додуматься извлечь fileId из коммента и добавить его в условие. Либо же можно передавать в метод setPartitionBy не только имя поля, а еще и id и тогда мы получим объект дерева для комментов только к одному файлу — вполне удобно.
Насчет MaterializedPathKeeper — тут есть недостаток что нельзя сделать больше одной иерархии в таблице. Это редко бывает нужно, я не могу с ходу придумать пример, но все же. Я погуглил, расширение doctrine-tree-extension имеет тот же недостаток.
Расширение doctrine2-nestedset тоже как и ты требует от сущностей реализовать интерфейс: https://github.com/blt04/doctrine2-nestedset/blob/master/lib/DoctrineExtensions/NestedSet/Node.php
Мощное расширение Tree для доктрины описывает нужные поля через аннотации (пометки в комментариях) и тоже поддерживает только одно дерево: https://github.com/l3pp4rd/DoctrineExtensions/blob/master/doc/tree.md
Так что твой подход с MaterializedPathKeeper в общем соответствует существующим библиотекам. А вот MaterializedPathMapper — нет.
Надеюсь, я тебя не запутал.
Посчитай круглые скобки в строке 12
>>404884
> https://github.com/sqghub/uppu.ru/blob/master/model/CommentMapper.php#L80
> "`fileId`={$comment->getFileId()}"
Вот это очень плохо. Ты вставляешь данные прямо в SQL код вместо использования плейсхолдеров и передаешь куски SQL кода. Это скорее всего значит что функция спроектирована неверно.
Также, не очень правильно что ты задаешь Mpath в момент создания Comment из post-данных. Может ты его и не собирался никуда вставлять?
Мне кажется, это должно делаться при попытке сохранения. То есть ты задаешь parentId и вызываешь save для коммента и маппер в этот момент проставляет ему Mpath и после этого сохраняет.
Например в Doctrine, расширение для работы с деревом подписывается на событие вставки/удаления сущностей и соответственно при вставке/удалении меняет поля и делает нужные запросы.
Заметь что такая схема (маппер дерева вызывается перед и после сохранения и удаления сущностей) позволяет CommentMapper не знать о том какой тип дерева используется и менять их не переписывая код функции save.
> решение с $addCondition выглядит неудачным, но я не придумал, как еще обобщить
Есть такая идея: сделать «поля группировки», то есть ты можешь в маппере при создании указать по каким полям будет идти партицирование (разбиение на части):
$mpMapper->setPartitionBy(array('fileId'));
Соответственно mpMapper будет считать что в таблице не одно дерево, а N деревьев, у каждого свой fileId.
Либо же это можно передавать в конструктор чтобы не забыли.
Для универсальности, полей группировки может быть несколько (потому массив). решение с полями группировки удовлетворит 99% ситуаций, а для оставшегося 1% (когда надо группировать по хитрым условиям) в таблицу можно добавить дополнительное поле.
Дальше, мне кажется, имя таблицы надо передавать в конструктор MPMapper. Оно же не меняется в ходе работы.
Имена полей path, parent_id можно либо тоже передавать либо задать жестко.
Вот первый вариант, пришедший в голову:
$mpMapper = new MPMapper($db, 'comments', 'path', 'parent_id');
// генерирует путь для вставки в конец списка детей для данного файла и комментария
$path = $mpMapper->createPathForAppend($parentId, ['fileId' => $comment->getFileId()]);
$comment->setPath($path);
Соответственно $mpMapper знает имена полей и может сам сделать нужный запрос. В этом варианте MpMapper никак не взаимодействует с объектом Comment напрямую.
К сожалению при таком подходе полной абстракции от используемой системы хранения не получается так как CommentMapper должен содержать код работы с path и ты не можешь одним движением переделать его на использование Adjacency List или Nested Sets. Для этого надо поменять способ подключения маппера:
$mpMapper = new MPMapper($db, 'comments', 'path', 'parent_id');
$mpMapper->setPartitionBy(..);
$mpMapper->beforeInsert($comment); // маппер сам вычисляет путь и проставляет его в $comment
... вставляем сущность в БД ...
$comment->setId($id);
$mpMapper->afterInsert($comment); // вдруг он что-то хочет сделать после вставки
Здесь mpMapper должен сам додуматься извлечь fileId из коммента и добавить его в условие. Либо же можно передавать в метод setPartitionBy не только имя поля, а еще и id и тогда мы получим объект дерева для комментов только к одному файлу — вполне удобно.
Насчет MaterializedPathKeeper — тут есть недостаток что нельзя сделать больше одной иерархии в таблице. Это редко бывает нужно, я не могу с ходу придумать пример, но все же. Я погуглил, расширение doctrine-tree-extension имеет тот же недостаток.
Расширение doctrine2-nestedset тоже как и ты требует от сущностей реализовать интерфейс: https://github.com/blt04/doctrine2-nestedset/blob/master/lib/DoctrineExtensions/NestedSet/Node.php
Мощное расширение Tree для доктрины описывает нужные поля через аннотации (пометки в комментариях) и тоже поддерживает только одно дерево: https://github.com/l3pp4rd/DoctrineExtensions/blob/master/doc/tree.md
Так что твой подход с MaterializedPathKeeper в общем соответствует существующим библиотекам. А вот MaterializedPathMapper — нет.
Надеюсь, я тебя не запутал.
> какой тайпхинт?
function (File $file) очевидно. Это же объект класса File раз он называется $file, верно? Использование тайпхинтов защищает от ошибок — поставь его и увидишь что это так.
Тайпхинты надо ставить везде. где можно.
Плюс, IDE вроде PhpStorm или Eclipse используют их для умного автодополнения.
> Так а вдруг ты их захочешь иначе назвать? Или это лишний геморрой?
Ни разу в жизни не встречался с необходимостью. Да, лишний геморрой . Например ты должен в этом случае поменять все внешние ключи, ссылающиеся на таблицу, а это 2 запроса DROP KEY/AD KEY для каждого ключа.
По моему, так запрос становится менее читаем. Да и если хранить имена то не в DataBase, а в маппере. Он же у нас отвечает за взаимодействие с таблицей.
И если у тебя правильный подход то c таблицей comments работает ровно один класс и можно легко пройтись по нему поиском и переименовать.
>>Алсо, нужен тайп хинт.
> А здесь-то какой?
array может быть? Кроме имени класса, есть еще тайп хинты array и callable (принимает любой из 3 способов сослаться на функцию: строку. массив, Closure). Мануал, почитай:
http://php.net/manual/ru/language.oop5.typehinting.php
Также, когда ты делаешь дерево, стоит сделать еще один важный метод — validate. Он проходится по базе и ищет ошибки в дереве.
Ну к примеру для Mpath ошибки это нарушение условий:
— Mpath в пределах дерева уникален
— Mpath не может быть пуст
— parentId ссылается на существующую запись (это можно контролировать внешним ключом в БД)
— Mpath ребенка начинается с MPath родителя и содержит на 1 элемент больше
— Mpath соседних детей различается на один в последнем элементе (может не выполняться если мы не пересчитываем path при удалении)
— ???
Почему нужен такой метод? Потому что дерево — сложная структура, и работая с кодом, легко его сломать и повредить связи в БД. Глазом ты эти ошибки не увидишь. Удобно иметь инструмент, проверяющий целостность, который например можно вызывать раз в сутки по расписанию или по требованию.
В идельном мире конечно дерево не может сломаться. А в реальном, особенно когда в команде есть неопытные разработчики — запросто.
Особенно важен такой метод для структур вроде Nested Sets которые еще сложнее.
Если у тебя есть время, я советую сделать метод. Тогда можно будет проверить дерево вставкой нескольких тысяч комментариев и проверкой что все ок.
Еще советы.
В MPMapper операции «превратить путь в массив номеров» и обратная операция надо вынести в отдельные функции. Так будет читабельнее + можно легко поменять способ хранения mpath
> if ($file->isMedia()) {
> $query = $this->dataBase->prepare("UPDATE
Это нужно внутрь транзакции
Также, тут надо подумать, а не лучше ли хранить объект MediaData внутри File? То есть мы можем писать
$file->getMediaData( )->getWidth( );
или
$file->getMediaData( )->isImage( );
(или $file->isImage( ))
Ну и вообще, мы можем потом надописывать любое число методов для работы с информацией о файле.
Мне кажется это лучше чем работа с сырым массивом в таком стиле:
> if ($mediadata['type'] == 'image')
> MediaDataMapper
название неудачное так как он не работает с БД напрямую
> substr_count($comment->getPath( ), '.')
Нарушение принципов инкапсуляции. Надо писать $comment->getDepth( )
Еще советы.
В MPMapper операции «превратить путь в массив номеров» и обратная операция надо вынести в отдельные функции. Так будет читабельнее + можно легко поменять способ хранения mpath
> if ($file->isMedia()) {
> $query = $this->dataBase->prepare("UPDATE
Это нужно внутрь транзакции
Также, тут надо подумать, а не лучше ли хранить объект MediaData внутри File? То есть мы можем писать
$file->getMediaData( )->getWidth( );
или
$file->getMediaData( )->isImage( );
(или $file->isImage( ))
Ну и вообще, мы можем потом надописывать любое число методов для работы с информацией о файле.
Мне кажется это лучше чем работа с сырым массивом в таком стиле:
> if ($mediadata['type'] == 'image')
> MediaDataMapper
название неудачное так как он не работает с БД напрямую
> substr_count($comment->getPath( ), '.')
Нарушение принципов инкапсуляции. Надо писать $comment->getDepth( )
Спасибо, только теперь регулярка не работает. Ненавижу регулярные выражения, но хочу выучить php и доказать, что могу сделать что-то до конца, чёрт побери.
У тебя регулярка имеет вид:
(выражение1)? ... (выражениеN)?
То есть все выражения могут отсутствовать. Получается что в этом случае регулярка соответствует любому тексту (пустая регулярка совпадает с любым текстом, точнее с всеми промежутками между буквами в нем).
Ты наверно хотел тут использовать символ «или » |
Перечитай мой урок про него и мануал: http://php.net/manual/ru/regexp.reference.alternation.php
>Вот это очень плохо. Ты вставляешь данные прямо в SQL код вместо использования плейсхолдеров и передаешь куски SQL кода.
Я по этому поводу откомментил в классе мпаса. Я тоже считаю что это хреновая идея, но ничего другого не придумал.
>Заметь что такая схема (маппер дерева вызывается перед и после сохранения и удаления сущностей) позволяет CommentMapper не знать о том какой тип дерева используется и менять их не переписывая код функции save.
Я немного пьян и плохо воспинимаю информацию, но вроде бы моему мапперу тоже наплевать на тип дерева и коду функции save тоже плевать.
>Есть такая идея: сделать «поля группировки», то есть ты можешь в маппере при создании указать по каким полям будет идти партицирование (разбиение на части):
Это сейчас не пойму. Попробую разобрать завтра.
>Дальше, мне кажется, имя таблицы надо передавать в конструктор MPMapper. Оно же не меняется в ходе работы.
Так вроде идея была в том, что пути могут использоваться в для разных таблиц. Потому и класс отдельный. Мол, вдруг мы хотим деревья файлов запилить, а у нас тут и интерфейс уже готовый.
>>404919
> Да, лишний геморрой .
Уберу завтра все упоминания тогда.
>По моему, так запрос становится менее читаем.
Определенно так, я просто уступал вероятности других имен. Как в том случае, когда ты предложил "config.local.php".
Про тайп хинты завтра тоже все пересмотрю, чего не додумаю сам - спрошу. Про MatPath тоже завтра, если вспомню.
А вообще хотел бы тебя поблагодарить: я давно понял, что мне нравится программирование, но у меня не было возможности ему учиться (а я учусь на вышке, связанной с этим делом, лол). Спасибо, что ты возишься со мной.
Конечно решаю.
http://ideone.com/2bCzix
Вот, регулярка проверяет на ошибки и выводит, где ошибка, но у меня проблема возникла. Как проверить запятую перед "а"?
Если я просто указываю пустое "а" в регулярке, то его находит везде, а с флагами ^$ его не находит.
http://ideone.com/2bCzix
>Насчет MaterializedPathKeeper — тут есть недостаток что нельзя сделать больше одной иерархии в таблице.
Можно добавить в интерфейс метод getPartitionBy(){return array()}
Таким образом у нас реализуются и несколько иерархий, и будет откуда брать поля группировки.
1) есть ли какая годная библиотека для рисования графов, чтобы красиво и без пересечений? Или хотя бы просто строить кружки и связи с минимумом пересечений? Если нет, то в сторону чего копать?
2) вот ты совет уешь читать официальную документацию вместо книг. Если осилю русскую версию - считай, знаю "все"?
3) есть ли эта документация в удобном виде типа PDF, чтобы читать в онлайне с планшета?
4) что читать по MySQL и другим базам, чтобы без задротства и изучения полной документации, а так, на достаточной уровне для работы?
>> if ($file->isMedia()) {
>> $query = $this->dataBase->prepare("UPDATE
>Это нужно внутрь транзакции
Зачем? Я специально вынес.
>Также, тут надо подумать, а не лучше ли хранить объект MediaData внутри File?
С медиадатой я вообще много чего думаю переделать, но позже. В конце концов - та же библиотека getID3 позволяет не только с музыкой и видео работать.
>название неудачное так как он не работает с БД напрямую
Исправлю позже.
С mpMapper'ом я что-то попробовал: https://github.com/sqghub/uppu.ru
>Также, когда ты делаешь дерево, стоит сделать еще один важный метод — validate. Он проходится по базе и ищет ошибки в дереве.
Займусь позже. Пора уже todo лист составлять, лол.
> есть ли какая годная библиотека для рисования графов, чтобы красиво и без пересечений? Или хотя бы просто строить кружки и связи с минимумом пересечений
Я слышал про эту — http://www.graphviz.org/Gallery.php Правда, она не на PHP.
Также, есть яваскриптовая http://d3js.org/ но она не совсем для графов.
> Если осилю русскую версию - считай, знаю "все"?
Считай что знаешь язык PHP. Но еще есть ООП, MVC, HTML/CSS/JS/SQL, фреймворки. У нас есть задание сделать файлообменник как раз для тех, кто язык освоил.
> есть ли эта документация в удобном виде типа PDF,
Есть в HTML и CHM: http://php.net/download-docs.php
> что читать по MySQL и другим базам,
У меня есть ссылки + пара задачек: https://gist.github.com/codedokode/10539213
> Можно добавить в интерфейс метод getPartitionBy(
По идее за взаимодействие с БД отвечает маппер, там это делать уместнее наверно.
>>Это нужно внутрь транзакции
> Зачем? Я специально вынес.
Так а зачем? Разве не логично одной транзакцией и файл в базу внести и информацию о нем дописать? Или какая-то причина есть?
> С mpMapper'ом я что-то попробовал:
По моему лучше не стало. Зачем например сюда
SetPathByParentId(MaterializedPathKeeper $keeper, $tableName, $partitionData)
передавать имя таблицы? Оно может быть разным? Если не может быть то наверно лучше один раз его при создании указать, а не передавать каждый раз.
Ну и сама функция, это длинная портянка, ее надо разбивать на более мелкие функции.
Ну и вариант с before/afterInsert, по моему, более универсальный так как позволяет поменять способ хранения.
> с флагами ^$ его не находит.
Так и должно быть
^а$
Обозначает строка из одного символа «а».
тебе надо искать последовательность вроде:
буква пробелы «а»
ты зря на слова разбиваешь, мне кажется. Так ты не можешь найти отстутсвие запятой перед «а». Это проще найти поиском по всему тексту.
Вы видите копию треда, сохраненную 5 декабря 2014 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.