... Но прежде чем начинать! Код надо писать не как попало, а аккуратно и красиво. Почему? Потому, что на неакуратно написанный код не хочется даже смотреть.
Если тебе лень выравнивать код руками, закачай его на http://beta.phpformatter.com/ и нажми «format». Робот исправит выравнивание и отступы в мгновение ока (да, прогресс не стоит на месте).
Самый распространенный стандарт оформления — это Zend Coding Guides (http://framework.zend.com/manual/1.12/en/coding-standard.html — на англ. яз.), вот его суть:
- переменные и функции пишутся с маленькой буквы, _ не используется, используется 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 ставятся так:
if (...) {
// ...
} else {
// ...
}
for (...) {
// .....
}
function makeMeFeelGood(...)
{
// ...
}
Как установить PHP под Windows? Картинка слева.
Как установить Апач самому? Паста → https://gist.github.com/anonymous/946f4f1830be3955fe17
Как начать пользоваться командной строкой? Паста → https://gist.github.com/anonymous/2dfa134fe20d9cf91bbe
Как установить PHP, продолжение.
Проясните за валидацию форм. Учусь по видеокурсам на ютубе, там автор абсолютно любой запрос, любую форму проверяет очень громоздкими конструкциями как на пикрелейтед. Причем неважно что некоторые значения устанавливаются автоматически, например в скрытых полях и никаким путем вписать туда пустое значение нельзя. Это правильно или чел просто копипастит шаблон, а я перенимаю хуевые привычки?
>>333488
>в скрытых полях и никаким путем вписать туда пустое значение нельзя.
Тебе так кажется.
>>333488
> Причем неважно что некоторые значения устанавливаются автоматически, например в скрытых полях и никаким путем вписать туда пустое значение нельзя
Проверять все равно надо. Ведь злоумышленник может отправить POST-запрос не браузером, а скриптом, или же подменить значения полей в браузере и подставить вообще любые значения.
> Это правильно
Писать нечитаемую лапшу, конечно, неправильно. Лучше сделать проверку отдельной функуией:
$age = isset($_POST['age']) ? intval($_POST['age']) : 0;
$name = isset($_POST['name']) ? $_POST['name'] : '';
$data = array(
'age' => $age,
'name' => $name
);
$result = validateForm($data);
function validateForm(array $data)
{
if ($data['age'] < 18) {
return "Вам должно быть больше 18 лет";
}
if ($data['age'] > 70) {
return "Вам должно быть не так много лет";
}
return true; // все ок
}
>>333513
Ну как переделать мой код, чтобы он возвращал все ошибки, а не останавливался на первой, я думаю, ты догадаешься сам.
Если полей оч много (например 20), можно сделать описание формы массивом (до ООП ты вряд ли дошел, так что пока по-простому) и сделать универсальную функцию-проверяльщик, которая проверяет поля на основе правил из массива:
$fields = array(
'age' => array(
'type' => 'integer', // делает intval(), чтобы прошли только числа
'nonempty' => true, // обязательно должен быть заполнен
'between' => '18-70', // должен быть от 18 до 70
),
'name' => array(
'type' => 'string', // имя — строка от 3 до 30 символов, обязательно
'nonempty' => true,
'maxlength' => 30,
'minlength' => 3
),
....
);
$rules = array(
'age' => 'integer, between 18-70, nonempty',
'name'=> 'string, minlength 3, maxlength 30, nonempty',
.....
);
>>333515
в ООП принципиально новый подход будет к проверке разве?
>>333517
Ну в Zend_Framework например форма сделана объектом, валидаторы для полей тоже отдельными объектами. Не то что принципиально новый подход, но немного по-другому. В фреймворках обычно не надо писать код проверки руками, а ты просто описываешь правила для полей (а код проверки уже встроен в фреймворк). И не только проверки, но и например, код для вывода формы тоже уже есть, он создает HTML-код формы по описанным тобой полям.
>>333517
Нет, в ООП и в фреймворках всё будет значительно проще и быстрее. Поскольку бОльшая часть валидирующего кода там уже написана и тебе остаётся только задать критерии валидации.
ОП, помоги пожалуйста с задачкой. Я даже алгоритма не смог придумать который сможет реализовать все это, а сделать нужно. Суть такова: есть текстовый файлик, куда написаны теги html. Скрипт должен прочесть этот файлик ивывести OK если порядок тегов правильный и нет ошибок в них, если же где-то есть ошибка, то вывести номер строки в которой она допущена. Не нужно проверять названия тегов и прочее, нужно лишь проверить является ли это тегом (открывающий и закрывающий уголок, возможно какие-то атрибуты), и если является проверить, имеется ли закрывающий тег. Открывающий тег может быть на одной строке, а закрывающий на другой. Условие таково, что ошибка будет только в том случае, если тег разделен построчно или после <body> идет сразу </html>, без закрытия <body>. Пикрелейтед задание в целом. Как его сделать вообще не понимаю. Подскажи пожалуйста.
>>333513>>333515
Меня интересует скорее логика таких проверок(на isset и empty), для тех форм которые заведомо "не опасные", что ли.
Например, есть форма редактирования статьи в админке, которая появляется при клике на кнопку edit. В этой форме можно поправить текст и заголовок, а остальные данные - id, автор, время написания - передаются в скрытых полях. Текст и заголовок не могут быть пустыми, ок, но зачем кому-то с разрешенным доступом в админку пытаться вписать в базу пустые значения id, автора и времени? Угробить базу из админки можно и проще же. Другой пример - есть форма фильтрации товаров, например, машин. На ней три селекта - новая/подержанная, иномарка/отечественная и красная/синяя. Пустые значения там никак не выберешь, в базу ничего не пишется, по идее достаточно mysql_real_escape_string от инъекции и все. Тем не менее лектор видеокурсов проверяет абсолютно все на свете на isset и empty.
Насчет нечитаемой лапши он оговаривается что это для экономии времени, в отдельном уроке показывает как правильно делать, примерно как у тебя.
>>333148
>Вообще, у тебя хорошо получается решать задачки. К тому же ты проверяешь свой код перед тем, как его показывать. Это плюс.
Спасибо, доброе слово и макаке приятно :3
Хотя особо радоваться нечему - я уже достаточно долго говнокодингом занимаюсь, правда, пугающе нерегулярно. Будь на моём месте кто-нибудь более целеустремленный, давно бы уже к успеху пришел.
Я даже поработать с месяцок успел, где как раз и выдрессировали хотя бы в первом приближении тестирование проводить.
Сейчас опять хочу где-то через месяц устраиваться, но в этот прийти на работу более-менее подготовленным и избежать того панического состояния, когда вообще не понимаешь что и как делать, а сроки колом стоят.
Код поправил, замечания принял к сведению.
Хитрый трюк с транспозицией (так вроде называется?) матрицы через array_map() очень крут.
Кстати. Встретил очень занимательно написанную серию статей про функциональные возможности PHP, может кому интересно будет: http://www.recessframework.org/page/functional-php-anonymous-functions-lambdas-closures
Еще спросить хотел, есть ли какие-нибудь реальные применения ф-ции array_reduce для рядового уеб-кодерка?
>>333532
> Меня интересует скорее логика таких проверок(на isset и empty), для тех форм которые заведомо "не опасные", что ли.
Если это админка, которой пользуешься только ты, это другое дело, ты можешь вообще ничего не проверять. Но ведь кроме злонамеренных изменений, есть еще баги, например из-за бага в форму в невидимое поле подставляется кривое или пустое значение. Если не делать проверок, то ты сам того не заметив, поломаешь данные в базе.
> Тем не менее лектор видеокурсов проверяет абсолютно все на свете на isset и empty.
Это чтобы варнинги не сыпались если параметр не передан.
>>333528
Используй стек (гугли, гугли). Когда ты встречаешь открывающий тег, кладешь в стек наверх его имя. Когда встречаешь закрывающий, снимаешь со стека верхний элемент и сравниваешь, совпадают они или нет.
>>333539
Ты вопрос ОПа прочел? Где там слово регулярки? Алсо, автор ответа не прав, я не раз парсил (X)HTML регулярками и все работало, и проблем не было. Алсо, автор ответа похож на рубиребенка. Как я это угадал? По последней строчке:
> Have you tried XML parser instead
>>333538
>Это чтобы варнинги не сыпались если параметр не передан.
А вот эта конструкция как тебе? Дурной тон или ок?
Всякое упоминание подавления ошибок которое я встречал было в контексте того, что это зло и бэд прэктис (ну кроме разве что парсинга html, да и то с оговорками), но вот в этом случае вроде как достаточно красиво получается.
$name = @$_POST['name'] or $name = 'имярек';
>>333544
Хэй-хэй, это слегка рилейтед шуточка же. Смешная как по мне.
Как я понимаю, регэксами html парсить имеет смысл когда точно знаешь, что твой html валидный и знаешь, какое подмножество языка тебе встретится.
Алсо, в чем проблема использовать XML парсер в PHP? Тот же DOMDocument.
>>333536
> есть ли какие-нибудь реальные применения ф-ции array_reduce
По идее функции вроде filter/map/reduce (которая еще называется в других языках fold) придуманы для сокращения количества кода, чтобы не надо было писать циклы. Но в PHP они довольно-таки криво сделаны, и сам синтаксис PHP к краткости не располагает, так что я таких применений не могу припомнить. Я обычно использую только:
$a = array_filter($b); // убрать пустые элементы из $b
$x = array_map('trim', $y); // очевидно зачем
Вывод массива в строку вида «a=12, b=13, c=15»:
$data = array('a' => 12, 'b' => 13, ....)
echo implode(', ', array_map(function($value, $key) { return "$key=$value"; }, $data));
Все это можно сделать и циклом (и работать будет быстрее), но цикл займет больше места, его дольше писать и дольше читать.
В других языках эти функции имеют гораздо больше применений (я надеюсь, проходящие мимо питонщики, хаскеллисты и рубисты подкажут пару примеров). Вот, например, генерация квадратов чисел от 1 до 10 в Руби:
(1..10).map { |n| n * n }
Аналог на PHP выглядит так:
array_map(function ($n) { return $n * $n; }, range(1, 10));
Чуть больше лишнего текста выходит. Но это все равно короче, чем писать цикл.
В хаскелле все эти штуки сделаны еще круче. Вот, например, подсчет суммы списка с помощью fold (аналог array_reduce): fold (+) [1,2,3,4,5] . Здесь (+) — это функция, которая равносильна такой: function ($a, $b) { return $a + $b; }, а все вместо равносильно такой строчке кода: array_reduce(array(1, 2, 3, 4, 5), function ($a, $b) { return $a + $b; }, 0);
Еще замыкания удобно применять с preg_replace_callback, это очень мощная функция.
В общем, иногда эти штуки позволяют сократить объем кода и улучшить читабельность. Думаю, стоит уметь ими пользоваться, тем более что они есть и в яваскрипте (через библиотеки вроде underscore/lodash) и в других языках.
>>333550
> Алсо, в чем проблема использовать XML парсер
1) HTML != валидный XML, потому просто XML парсер не катит. Нужен именно HTML парсер.
2) В HTML закрывающие теги могут быть пропущены иногда, валидный пример кода: <ul><li>1<li>2<li>3</ul>
3) При этом, никто не обещал что HTML будет валидным
4) Но при этом, DOMDocument::loadHtml обычно работает корректно
Также, DOM дольше работает, когда тебе надо обрабатывать большие (>= 1 Мб) или много документов потоком, и при этом брать из них только пару значений, проще и быстрее использовать регулярку. Хотя, DOM, если прикрутить к нему поиск по CSS3-селекторм или хотя бы XPAth, тоже неплохая вещь. Огромные XML лучше обрабатывать не DOM (который съест всю память), а потоковым XMLReader-ом.
В общем, надо смотреть по ситуации.
>>333547
Дурной. @ = быдлокод
Если тебе лень писать каждый раз isset, в чем проблема поместить isset в функцию и использовать ее? Например: $name = ge('name');
>>333560
>в чем проблема поместить isset в функцию и использовать ее?
Гм, логично.
>@ = быдлокод
Можешь развернуть? Почему конкретно в этом примере это плохо, кроме того, что @ - плохо и не модно само по себе? Я просто не понимаю, какие тут подводные камни и встречал эту конструкцию на stack overflow, там вроде никто не плевался.
>>333536
Вот еще интересная вещь: итераторы в PHP. Вот пример, какие штуки можно вытворять с рекурсивным массивом: http://ideone.com/hk9bfN
Еще советую посмотреть RecursiveDirectoryIterator, им можно рекурсивно обходить файлы на диске в несколько строк.
>>333565
Оно подавляет любые ошибки, в том числе и те, которые ты не хотел бы подавлять. Особенно опасно, когда @ стоит перед вызовом функции, которая вызывает еще 20 функций и во всех них тоже появляются ошибки. Ошибки должны фиксироваться, и потому проще в принципе говорить что @ плохая и запрещать ее везде, чем делить на случаи. Плюс, разрешив @ в проекте, ты в итоге придешь к тому, что ее будут лепить где попало. Потому проще сделать функцию ge(), чем переходить к друным практикам написания кода.
Пример: $x = @$array['x']; предполагается что @ нужна для обхода случаев когда в массиве нет элемента. Но (внезапно) она скроет и ошибку, когда $array не существует или не является массивом. Используя @ мы делаем код хуже.У нее столько подводных камней, что проще от нее отказаться.
>>333532
Только сейчас заметил:
> достаточно mysql_real_escape_string от инъекции и все.
Расширение mysql и функции mysql_* давно устарели, сейчас модно использовать либо ООП-расширение PDO, либо (если ты никак не можешь отвыкнуть от mysql_query) mysqli, но лучше бы PDO.
Так что если не хочешь выглядеть например на собеседовании как пришелец из прошлого, изучи потом PDO. Ну и ознакомься с http://www.phptherightway.com/ (русский? http://getjump.github.io/ru-php-the-right-way/ )
Анон как-то спрашивал, как прибавлять даты в PHP. Нашел новый способ, с использованием класса DateTime: http://getjump.github.io/ru-php-the-right-way/#Дата_и_Время
>>332256
Ох, что то тяжко идёт освоение Yii. Читаю и выполняю "Создание блога с использованием Yii". http://yiiframework.ru/doc/blog/ru/start.overview
Но плохо понимаю, то что я делаю. Такое ощущение, что учу как-то неправильно.
Сколько времени уходит на то чтоб научиться делать в yii что-нибудь простое, но самостоятельно?
>>333615
Гыйи нужен для того, чтобы не увели заказ на сторону.
Переусложнённость, как правило никому не нужная - от этого.
Web, что поделать.
Аноны. Не могу додуматься. Маны перечитал пару раз и все что понял это вот:
" /^8[-|(]([0-9]{3})[)|-|(][0-9]{3}[)|-|(][0-9]{4}/ " рег.выражение, которое проверяет правильность введеного номера. [)|-|(] - значит что в этом месте может стоять как ), так и -, такт и ( или же все три сразу, верно?
Задание с archive-ipq-co.narod.ru.
Есть необходимость хранить в базе HTML-код статьи, то есть текст вместе с тегами, например
<h1>Заголовок статьи</h1>
<p>Текст абзаца<a href='#'>Ссылка</a></p>
Проблема заключается вот в чем - когда делаю сокращенный вывод, скажем, первые 100 символов и ссылку "... read more" может получиться так, что substr($text,0,100) разорвет какой-то тег, например <a href='' class=''> где-нибудь посреди атрибутов и тогда вообще весь остальной текст страницы окажется текстом этой ссылки.
Должна же быть изящная функция для этого без лишней ебатни?
>>333615
Узнаю себя в твоём посте. Когда читал - думал ебанусь со всего этого. Ну никак не мог вкурить что там и как. Проблема в том, что документация написана в таком ключе, что типо "вот то то мы делаем так и так (но можно и так, и вот так тоже можно)" но оно не даёт СИСТЕМНОГО ПОНИМАНИЯ. Моя тебе рекомендация - запили какой нибудь проектик на нём. Попутно пользуй гугл и класс референс. Я например сейчас просто кончаю радугой с ЙИИ и думаю все свои простенькие быдло-проэктики на него перетащить. Причина проста - разработка тех самых проектов с нуля на фреймворке займёт на много меньше времени, чем их поддержание в текущем их состоянии.
> Сколько времени уходит на то чтоб научиться делать в yii что-нибудь простое, но самостоятельно?
Прошло примерно 20 рабочих часов, пока на меня снизошло тотальное понимание. Сайчас чувствую себя богом веб-разработки.
Алсо, Аноны, стоит ли упарывать симфони или зенд? И какие профиты можно с них получить по сравнении с ЙИИ?
>>333631
Вопрос не актуальный, в моем случае приемлемо substr(strip_tags($text),0,100) но вообще, погуглив удивлен тем что задача легкой обрезки html-кода далеко не тривиальная.
Антоны, тред что-то иногда висит и выдает vocaroo, так что я даже написать ничего не могу. Пишите мне на почту (адрес внизу сайта) если у вас есть вопросы или хотите проверить решение.
>>333618
Ты пишешь бред.
>>333615
Не знаю, от нескольких дней до недельки-двух. Ты попробуй хотя бы для начала сделать главную страницу с формой загрузки файла, хотя бы без оформления, и выложи куда-нибудь,а я подскажу куда дальше двигаться.
>>333621
Нет, не так. | внутри квадратных скобок значит не «или», а просто «вертикальная палка». Потому
[)|-|(] значит что в этом месте может быть один из символов ) | - или ( но не все 3 сразу
[)|-|(]+ — значит что тут может быть от 1 до бесконечности любых из этих символов в любом порядке
[)|-|(]{3} — значит что тут должно быть любые 3 символа из указанных в любом порядке
Алсо, внутри квадратных скобок большинство символов не имеет специального значения. | ? * ( ) { } — все эти символы просто обозначают сами себя. Но вот минус внутри квадратных скобок значит «от и до», например 0-9 — от 0 до 9, a-z от a до z. И если ты хочешь написать просто минус, то ставишь его либо в конец [0-9./+-] либо добавляешь бекслеши [0-9\\-./+]
>>333640
> Алсо, Аноны, стоит ли упарывать симфони или зенд?
Если ты их поймешь, то почуствуешь себя богом архитектуры в сравнении с теми, кто использует примитивные фреймворки вроде Yii. Учти, что там есть ZF1 и ZF2 и Symfony 1 / 2 и они сильно различаются. 2-е версии конечно круче.
> но оно не даёт СИСТЕМНОГО ПОНИМАНИЯ
Да, есть такое. Люди, которые привыкли писать кривые скриптики, где все в кучу, не сразу понимают преимущества правильной архитектуры и разделения кода на MVC, виджеты, валидаторы и что там еще есть.
>>333631
> Должна же быть изящная функция для этого
О, можно будет сделать из этого задачку и давать анонам.
Привет братве, привет доброкунчик. Такой вопрос: мне нужно чтобы некоторый скрипт постоянно висел в памяти, и раз в N минут делал кое-какие проверки. Я могу это просто набылокодить в своем коде, но дело в том, что задача для приложения, в котором участвую неск-ко человек. Разработка на Yii. Поэтому все должно быть максимально прилично. Там еще куча всяких условий, но мне как это принципиально делается, в концепции MVC и Yii. Может у кого есть опыт?
>>333705
Если раз в N минут, используй крон, который будет вызывать твой cli-скрипт (cli = для командной строки) раз в N минут. Это традиционный способ.
Для создания cli-скриптов в Yii есть готовые средства: http://www.yiiframework.com/doc/guide/1.1/en/topics.console
Чем плох вариант «постоянно висеть в памяти»? Как минимум тем, что тебе надо писать/искать и настраивать супервизор, который будет его перезапускать в случае падения и оформить все это как службу, чтобы оно запускалось при перезагрузке сервера. Думаешь, проще перезапустить руками? ну попробуй, раз на двадцатый ты поменяешь свое мнение.
>>333697
>научиться делать в yii что-то простое → от нескольких дней до недельки-двух.
>Ты попробуй хотя бы для начала сделать главную страницу с формой загрузки файла
Я так понял, для начала сделать это без Yii? Потому что на данном этапе я пока пытаюсь понять что к чему там.
>>333711
Мне нужно чтобы этот скрипт запускался только если определенный тип пользователей зашел в систему. Пользователи разделены по ролям. Если заходит нужный пользователь, то этот скрипт запускается, и запускает крон. Как-то так. Ладно, спасибо вобщем за ссылку. Кстати, я в прошлом треде спрашивал про грид и отдельную форму поиска для него - с большим трудом я это сделал!
>>333712
> Потому что на данном этапе я пока пытаюсь понять что к чему там.
Если ты будешь много читать теорию и мало уделять практике, трудно будет что-то понять.
Для начала, если ты не читал, почитай мануалы. Слишком не увлекайся, просто ознакомься. Например, такие:
http://www.yiiframework.com/doc/guide/1.1/ru/basics.mvc
http://borisnote.wordpress.com/2011/07/29/yii-create/
Там есть урок «создание первого приложения». В нем создается пример приложения, ты можешь его взять и просто поменять главную страницу для начала.
В том уроке правда нужно пользоваться командной строкой. У меня есть паста на эту тему: http://gist.github.com/anonymous/2dfa134fe20d9cf91bbe
В общем, попробуй освоить просто создание приложения как там описано. Если что-то непонятно или не работает — пиши, будем разбираться. Если проблемы с командной строкой — сразу прикладывай скриншоты или копипасть текст ошибки.
>>333716
Кстати
>>только если определенный тип пользователей зашел в систему
это как раз не сложно. Я что-то не додумал
>>333716
> то этот скрипт запускается, и запускает крон
Не, ты не можешь запустить крон.
> Мне нужно чтобы этот скрипт запускался только если определенный тип пользователей зашел в систему.
Ну смотри. Если скрипт короткий и быстро работает, можно вставить его в то место, где происходит авторизация. Это просто.
А вот если скрипт длинный, то его нельзя просто так вставить, так как страница будет долго загружаться, зля пользователя, или что хуже, отвалится по таймауту и твой скрипт сдохнет на полпути, попутно поломав базу (чтобы не поломал, можно завернуть все в транзакцию, которая отменится при падении скрипта). Некоторые решают это костылем: скрипт запускают в фоне аякс-запросом со страницы. Это конечно сомнительное, ненадежное и велосипедное решение. Никто не гарантирует, что пользователь не перейдет на другую странцу или закроет вкладку.
Можно запускать скрипт отдельным фоновым процессом из PHP, через команду вроде exec('nohup php myscript.php & ') — минус такого подхода, что ты никак не контролируешь что происходит дальше и не получаешь обратной связи. Ну зато это несложно. Может тебе подойдет такой вариант.
Еще это реализуют через очередь задач: когда нам надо что-то сделать, мы добавляем задание в очередь. Специальный демон или крон-скрипт постоянно проверяет очередь, берет из нее задачи и запускает воркеров для выполнения, следит за ними, пишет логи. Это можно даже делать в несколько потоков, такие системы уже есть готовые, например http://gearman.org/
В общем, не знаю, очередь задач ради такой простой вещи наверно слишком круто, но знай, что такие штуки есть. Например, очередь задач можно использовать для конвертации видео, загружаемого пользователем на местный клон ютуба.
>>333567
>итераторы в PHP
А yield и генераторы ещё пока в php не завезли?
Как мне в RegularExpression искать слова от 4 букв на любых языках без цифр?
http://dumpz.org/722942/
Оп, не слишком ли это быдлокодно?
У меня весь код в таком стиле.
Всё ещё тот кун, который не доделал обменник на Slim Framework.
>>333769
Ну круто конечно, но по ссылке только поле для ввода пароля. Если ты не хочешь никому показывать код, то можешь скинуть мне на почту, но было бы конечно лучше, если бы и другие аноны могли его посмотреть, и может быть что-то для себя уяснить.
>>333771
А с русскими буквами в utf-8 будет работать? В мануале написано, что \w зависит от локали, и как я понимаю, вся это чудо хрень принципиально не может в utf-8. Зато есть вот такая штука: http://www.php.net/manual/ru/regexp.reference.unicode.php
Чтобы написать «буква на любом языке (как и просил анон)» можно использовать \p{L}
>>>>333773
Транзакция, имеется в виду транзакция в базе данных. Это штука, которая позволяет сделать пачку запросов так, что они либо все 100% выполнятся и сохранятся, либо все отменятся.
Ну типичный пример — банк: когда Вася переводт деньги Пете, мы должны убавить баланс Васи (запрос #1) и прибавить баланс Пети (запрос #2). Ну и скорее всего сделать еще несколько запросов для сохранения логов, статистики и подобных вещей. Если вдруг посередине операции произойдет что-то вроде перезагрузки сервера, ошибки в PHP скрипте или потери соединения, то мы окажемся в неприятной ситуации: деньги у Васи сняли, а Пете не зачислили. Чтобы этого не было, всю последовательность операций заворачивают в транзакцию. Она либо полностью выполнится, либо не выполнится ни одного запроса.
Плюс, транзакции могут еще изолировать изменения. Например, скрипт добавляет запись в таблицу, и он эту запись видит, а другие скрипты видят исходную таблицу, они увидят добавленные данные только когда транзакция будет завершена.
В MySQL есть такие команды: BEGIN (TRANSACTION) - начинает транзакцию, COMMIT — завершает транзакцию и атомарно вносит изменения, ROLLBACK — откатывает транзакцию.
В общем, читай http://ru.wikipedia.org/wiki/%D0%A2%D1%80%D0%B0%D0%BD%D0%B7%D0%B0%D0%BA%D1%86%D0%B8%D1%8F_(%D0%B8%D0%BD%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0)
http://www.mysql.ru/docs/man/ANSI_diff_Transactions.html
>>333773
Теория про уровни изоляции транзакций: http://habrahabr.ru/post/135217/
Еще, кстати, транзакции в некоторых случаях ускоряют вставку записей в MySQL. Например, вставить 10 записей одной транзакцией обычно быстрее, чем 10 отдельными запросами (по сути в этом случае каждый запрос идет как одна транзакция). Почему? Потому, что при записи транзакции MySQL сбрасывает данные на диск и ждет ответа от ОС, что все сбросилось, чтобы убедиться что данные надежно сохранены (а это не очень быстро), и ждать один раз быстрее, чем сбросить данные 10 раз подряд и 10 раз ждать.
>>333769
Цель задачи была — научиться использовать ООП и фреймворки, ну и наверно научиться MVC. Ну, фреймворк я тут конечно вижу, но вот с MVC, ООП как бы не очень.
> static $db = null;
В Slim можно использовать Resource Locator: http://docs.slimframework.com/#DI-Overview
Пишешь $app->container->singleton('db', function () { ...устанавливаем соединение ... }) и при обращении к $app->db он будет возвращать объект pdo.
> function render
В Slim и для этого есть решение: http://docs.slimframework.com/#View-Overview — зачем писать свой велосипед?
Если мало возможностей Slim, ты можешь определить свой View, унаследовав его от \Slim\View
> $search = isset($_GET['search']) ? htmlspecialchars($_GET['search']) : null;
Зачем htmlspeciachars?
> $search_results->execute
Нет. Код работы с Бд должен быть в отдельных классах. Сделай например класс FilesTable и в нем делай метод searchFiles($like).
Ну и конечно результаты поиска лучше бы сделать не глупым массивом, а объектом-моделькой File. Тогда ты можешь например вызывать разные методы вроде if ($file->isPicture()) { ... } и твой код будет лучше.
Также, у меня есть подозрение, что ты свалил весь код в один файл, если так то тоже плохо.
В общем, есть что улучшать.
>>333769
> $search_results_
Вот это особенно плохо. Мне пришлось вглядываться в экран, чтобы увидеть что это не у меня глюки, а действительно 2 разных переменных. Не делай так. А переименуй:
$search_results → $search_statement или $search_stmt
$search_results_ → $search_results или $files
>>333769
> while($a = $search_results->fetch()){
Открой для себя fetchAll: http://www.php.net/manual/ru/pdostatement.fetchall.php
>>333778
хммм а кто-нибудь знает подводные камни? почему не панацея в использование?
>>333790
Я не такой большой специалист по БД, так что о подводных камнях не знаю. Транзакции как раз и придуманы, чтобы снять с разработчика головную боль по обеспечению целостности данных.
ОП-кун, вот очередная задачка, на поиск пути. Жду комментов.
Вместо того, чтобы городить велосипеды реализовал алгоритм Дейкстры. Единственный косяк, если не считать потенциально неэффективных кусков кода, - то, что не обработан случай, когда из А в Б в принципе нельзя добраться.
Итераторы оно круто, конечно, на заметку возьму, но пока плотно изучать не буду.
Давно уже пора к ООП переходить, а я что-то просрал уже несколько дней вообще впустую, да и с задачками как-то долго уже вожусь.
а можете сказать как правильно вставлять данные из php в html страницу, шаблоны не самая оптимальная по производительности штука, использовать регулярные выражения для замены, тоже не оптимально
>>333913
согласен
а так нормально
что есть echo в самом html коде?
>>333913
> обрабатывать данные в бекенде нужно.
Это как? По моему, либо я тебя не понял, либо ты ошибаешься. htmlspecialchars — это не обработка данных, а перевод просто текста в HTML.
Правильно писать именно <?= htmlspecialchars($yoba); ?> чтобы любые символы, в том числе < > и & в $yoba выводились корректно и в соответствие с правилами HTML.
Плюс, как ты «обработаешь в бекенде» обращение к методам модели, например: <?= htmlspecialchars($project->getTitle()) ?>
Кстати, умные шаблонизаторы, (например Google Closure Templates или XSLT) делают htmlspecialchars сами.
Есть index.php, в который путем include подключаются остальные странички. Есть javascript-функция которая, например, запрещает ввод любых символов кроме цифр в строку, т.е. обычная вспомогательная функция. Используется она, допустим, на двух-трех из двадцати подключаемых страницах. И таких функций очень много. Как правильнее - вставить их все один раз в index.php или копировать по тем страницам где они реально нужны? В первом случае засираем индексный файл кодом, который может и не понадобится, во втором дублируем одни и те же куски по нескольким страницам.
>>333940
Копипастить — плохо.
Можно к каждой странице подключать 2 JS-файла: global.js — функции, которые нужны везде или почти везде, page-x.js — только на странице x. Эта твоя функция пойдет в global, а вызываться будет только там, где нужна.
Макаканы, помогите построить базу, с которой можно пилить сайты с нуля?
Для html и css - это boilerplate. Обнуление стилей классная штука, чтобы все элементы на странице выглядели во всех браузерах максимально похожи. Алсо там есть шаблонный .htaccess для Апача.
Далее: для JS нам пригодится html-shiv, чтобы IE не тупил с новыми HTML5-тэгами и jQuery.
Для mysql ничего не нужно.
А теперь самое главное: на чем строить php-скрипты? Около месяца разбирался с Zend 2. Это просто охренеть, какая монструозная и комплексная штука. Согласен, там есть модули на все случаи жизни, но сама повседневная разработка очень уж утомляет. Если я на чистом PHP за 15 минут склепаю форму и ее валидацию на стороне сервера, то для такой тривиальной задачи в Zend'e мне придется поебаться в 2 раза дольше. Там и злоебучая маршрутизация и сущности базы данных с гидратацией, это слишком для простого новостного сайта, скажем.
Но если писать на голом PHP, то я становлюсь неуверен в безопасноти. Постоянно опасаюсь SQL-инъекций. А в Zende все сделает за тебя класс взаимодействия с БД.
Как же быть, анон?
>>333862
Вообще, хорошо сделано, все работает.
Алгоритм Дийкстры, конечно, далеко не самый оптимальный способ поиска пути, но для этой задачи вполне подходит, так как тут очень мало точек. Когда точек очень много (например, поиск маршрута с учетом всех улиц или поиск пути в играх), используют другие алгоритмы. Дийкстра — универсальный алгоритм, и он ищет путь, распространяясь во все стороны, а другие алгоритмы оптимизируют поиск тем, что учиытвают координаты точек и в первую очередь проверяют те точки, которые находятся в направлении к цели.
Но для этой задачи он подходит. Небольшие замечания:
> extract($pathArray);
Ой, лучше явно брать значения вроде
$prevNodes = $result['prevNodes'];
$totalTime = $result['totalTime'];
а то с extract абсолютно непонятно сколько там будет переменных и каких.
> & laquo ;
Так тоже можно, но можно вставить (скопировать или ввести с клавиатуры, если у тебя типографская раскладка) сами символы «». Чем лучше? Тем, что « выглядит лучше и понятнее чем & laquo ; Чем хуже? Если кто-то откроет твой исходный код не в utf-8 символ покорежится.
Реализация алгоритма, конечно, выглядит как-то усложненно.
Заполнить массив можно не только циклом но и с помощью array_fill_keys (получается короче):
$pathTimes = array_fill_keys(array_keys($paths), NULL); или
$pathTimes = array_fill_keys($points, NULL); если названия точек вынести в массив
> $i = 0;
> while($i < $numNodes) {
> $i++;
Это ты пытаешься заново изобрести цикл for.
>>333948
> Обнуление стилей классная штука, чтобы все элементы на странице выглядели во всех браузерах максимально похожи.
Что еще расскажешь? А ты не забываешь после обнуления выставить назад все стили для всех элементов, которые ты сбросил или же как у 99% верстальщиков текст с тегами на твоей странице выглядит как сплошная серая полоса без отступов?
reset давно устарел, это даже на западе наконец-то поняли, и в том же bootstrap используют не reset, а normalize.css (ну а мне было очевидно с самого начала, что reset — это типичный быдлоскрипт для индусов, которым плевать на качество). Не советую его использовать, советую изучать CSS и знать особенности браузеров.
Бесит, когда на сайте например списки отображаются без отступов и точечек, или таблицы скособочены, или заголовки неправильно выровнены после применения reset.css
> Если я на чистом PHP за 15 минут склепаю форму и ее валидацию на стороне сервера
C подстановкой сообщений около нужных полей, сохранением значений, CSRF токеном и прочими плюшками? Да ну, сомневаюсь.
> помогите построить базу, с которой можно пилить сайты с нуля?
Фреймворки же, Yii например или ZF (но он сложнее) + расширения и плагины к ним + что-нибудь готовое для админки. Zend 2, конечно, не самая простая штука.
>>333948
> Обнуление стилей классная штука, чтобы все элементы на странице выглядели во всех браузерах максимально похожи.
Что еще расскажешь? А ты не забываешь после обнуления выставить назад все стили для всех элементов, которые ты сбросил или же как у 99% верстальщиков текст с тегами на твоей странице выглядит как сплошная серая полоса без отступов?
reset давно устарел, это даже на западе наконец-то поняли, и в том же bootstrap используют не reset, а normalize.css (ну а мне было очевидно с самого начала, что reset — это типичный быдлоскрипт для индусов, которым плевать на качество). Не советую его использовать, советую изучать CSS и знать особенности браузеров.
Бесит, когда на сайте например списки отображаются без отступов и точечек, или таблицы скособочены, или заголовки неправильно выровнены после применения reset.css
> Если я на чистом PHP за 15 минут склепаю форму и ее валидацию на стороне сервера
C подстановкой сообщений около нужных полей, сохранением значений, CSRF токеном и прочими плюшками? Да ну, сомневаюсь.
> помогите построить базу, с которой можно пилить сайты с нуля?
Фреймворки же, Yii например или ZF (но он сложнее) + расширения и плагины к ним + что-нибудь готовое для админки. Zend 2, конечно, не самая простая штука.
Алсо, советую лучше заниматься чем-то одним, например, бекендом на PHP, а верстку свалить на кого-нибудь другого, зачем тебе сидеть пиксели выравнивать, лепить костыли для ИЕ и скрипты отлаживать, когда ты можешь заниматься более высокоуровневыми вещами?
>>333955
А чем годен Yii? Самое основное, что мне нужно, это класс для работы с БД, зародыш админки и зародыш системы залогинивания.
>>333963
Там есть класс для работы с Бд, система залогинивания + куча расширений в сети разной степени годности.
>>333965
Пока читаю take a tour на офф. сайте спрошу такую вещь: планирую впервые в жизни пилить сайт, через который идут интернет платежи. Насколько сложно прикрутить к нему всякие Киви, Вебмани, Яндексы, PayPal'ы?
Скриптаны, хочу запилить свой сайт, чтобы приносил доход хотя бы 100$ в месяц. В какую тематику идти?
Алсо пилите ссылки на свои сайты, я хоть вдохновение буду черпать.
>>333970
Есть простое решение — подключить какую-нибудь универсальную систему типа робокассы, оно простое в плане времени, но с точки зрения удобства пользования ниже плинтуса, так как для оплаты там надо пройти 100500 экранов, на которых половина юзеров потеряет всякое желание платить. Если тебя интересует сделать как можно удобнее, то придется тщательно продумать процесс оплаты и интерфейсы и самому подключать все системы (нужно юрлицо и договор). Вдохновиться можно, походив и посмотрев системы оплаты на купонных сайтах, вконтактике, вкиви и подобных сайтах.
С точки зрения программирования все системы похожи: ты делаешь форму, подставляешь в нее всякие идетификаторы и сумму платежа. Когда пользователь оплачивает заказ, система отправляет на твой сайт POST-запрос с данными, ты либо принимаешь его либо отказываешься и если все ок, получаешь второй запрос, с уведомлением об оплате, после чего пользователя назад перекидывает. Можешь почитать тут например: https://money.yandex.ru/doc.xml?id=526025 - это у яндекса.
>>333976
> В какую тематику идти?
В /web. Здесь мы изучаем PHP.
>>333965
>система залогинивания
О, а проясните за авторизацию. Сейчас сделано так - в индексном файле проверка:
if ($_SESSION['logged_in']==true) {
//показываем саму страничку
} else {
//показываем форму логина
}
Форма, соответственно, при верно введенных данных записывает true в $_SESSION['logged_in'].
Все остальные файлы имеют проверку:
if ($_SESSION['logged_in']==true) {
//показываем саму страничку
} else {
//редирект на index.php
}
Понимаю что это полный примитив, но вроде норм работает.
>>333939
>Плюс, как ты «обработаешь в бекенде» обращение к методам модели
мы просто php учим или учим и придерживаемся принципов mvc?
Ок, может я неверно понял про htmlspecialchars, я к тому чтобы работать с фреймворками и отдавать переменные шаблонизаторам, да если и без них в контроллере готовить переменные а потом отдавать готовые во вьюху.
>>333986
Лучше бы вынести это в отдельный класс и писать if ($auth->isLoggedIn()), тогда если где-то ты меняешь правила или систему авторизации, ты делаешь это в одном месте, а не переписываешь весь код.
Ну а вместо
> редирект на index.php
лучше редиректить на форму логина с надписью «вам нужно залогиниться или зарегистрироваться для просмотра этой страницы», сохраняя адрес исходной страницы, чтобы после логина/регистрации перебрасывало назад.
>>333989
Мы учим MVC, и ты наверно что-то не так понимаешь. В контроллер выносить htmlspecialchars неудобно так как:
- контроллер перестает быть тонким и оказывается завален мусорным однотипным кодом
- мы не можем передать во вью модельку, так как должны вместо этого в контроллере писать:
$title = htmlspecialchars($project->getTitle())
$author = htmlspecialchars($project->getAuthor())
....
и еще строчек 10 такой лапши вместо того чтобы передать во вью единственную переменную $project.
- использование хелперов во вью никак не противоречит MVC, наоборот способствует порядку в коде. К хелперам относится не только htmlspecialchars, но и функции форматирования чисел, валют, дат, перевода строк, обрезки длинных строк, склонения числительных, имен и городов — все это удобнее вызывать в шаблоне.
- и наконец, как я сказал, некоторые шаблонизаторы сами автоматически делают htmlspecialchars
Заметь, что противоречия MVC тут никакого нет. Мы лишь используем во вью хелперы для оформления данных, мы не выносим туда никакой логики, не пишем там запросы к базе данных, не проверяем правильность заполнения формы и подобные вещи.
А есть здесь люди, которые разбирали исходники php?
Сначала я забил на свой обменник на Slim Framework, потом захотел попробовать Yii. В итоге я перенёс обменник на Yii (причем очень быстро). Теперь быдлокода меньше в 100 раз.
Но есть одна проблема:
У меня есть layouts/main.php (это основной шаблон, где подключаются js скрипты, стили)
И есть там шапка. Раньше реализовано было так:
http://dumpz.org/723747/
И всё работало. Не могу придумать, как сделать сейчас.
Макаканы, сотоит ли избегать нотисов по поводу существования переменной, либо ключа массива? Эти дополнительные isset убивают меня.
>>333253
> https://github.com/Somepony/php-wakabamark
> Ну а статей бы русских по использованию этого всего? Есть такое?
Подключаешь markUp.php (require "markUp.php"), а перед вводом (или выводом) в БД оборачиваешь переменную с текстом в функцию MarkPost(), например, MarkPost($message) или MarkPost($_post['message']).
>>334064
В Yii можно получить имя контроллера и action и в зависимости от них, выделять пункт меню. Например, как тут: http://shanideveloper.blogspot.ru/2012/01/yii-how-to-get-current-controller-name.html
Поместить этот код можно куда-нибудь в beforeAction() базового контроллера, от которого наследуются остальные (чтобы он выполянлся везде).
>>334066
Если тебе приходится isset всюду ставить, то скорее всего ты просто неправильно организовал хранение данных в программе и валишь все в сложный запутанный массив, в котором часть элементво может отсутствовать. Это крайне дурной подход. Надо его распутать.
Если же речь о GET/POST, то просто сделай функцию вроде getQuery('name') которая внутри будет делать isset.
>>334075
Лучше делать это в момент сохранения поста, и завести 2 колонки в таблице: post_source (исходынй пост) и post_html (обработанный). А то может быть дорого каждый раз при вызове делать все эти преобразования.
Анончики, выручайте (вы уже не раз мне помогали, я верю в вас). Есть софт-парсер, который шлет POSTом картинки скрипту (с помощью Curl), а тот сохраняет их на сервер. Нужно, чтобы скриптец также на лету также обрезал (crop) картинки. А он никак не хочет, зараза; GВ-library установлен, конечно:
// 1. GET IMAGES VIA POST
$imgpath = $_POST['img_url'];
$dirname = $_POST['img_folder'];
$imgid = $_POST['imgid'];
$ch = curl_init($imgpath);
$fn = ($imgid.substr($imgpath,strrpos($imgpath,'/')+1,strlen($imgpath)));
$fn = str_replace('?', '_', $fn);
$fn = str_replace('=', '_', $fn);
if (is_dir($dirname)==FALSE) mkdir($dirname);
$fp = fopen($dirname.'/'.$fn, 'wb');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
// 2. CROP IMAGE
$in_filename = $imgpath;
list($width, $height) = getimagesize($in_filename);
$offset_x = 0;
$offset_y = 0;
$new_height = $height - 40;
$new_width = $width;
$out_filename = $in_filename . '_crop';
$image = imagecreatefromjpeg($in_filename);
$new_image = imagecreatetruecolor($new_width, $new_height);
imagecopy($new_image, $image, 0, 0, $offset_x, $offset_y, $width, $height);
header('Content-Type: image/jpeg');
imagejpeg($new_image, $out_filename);
imagedestroy($new_image);
echo($dirname.'/'.$fn);`
$in_filename = '1111.jpg';
list($width, $height) = getimagesize($in_filename);
$offset_x = 0;
$offset_y = 0;
$new_height = $height - 40;
$new_width = $width;
$image = imagecreatefromjpeg($in_filename);
$new_image = imagecreatetruecolor($new_width, $new_height);
imagecopy($new_image, $image, 0, 0, $offset_x, $offset_y, $width, $height);
header('Content-Type: image/jpeg');
imagejpeg($new_image, 'crop.jpg');
imagedestroy($new_image);
ОП поясни про mvc, я правильно понимаю что контроллер только получает инфу с вьюхи, проверяет на существование необходимых данных а дальше все отправляется в модель, где проходит уже валидация, бизнес-логика и т.д.
>>334149
Вообще, контроллер — это как директор, который сам почти ничего не делает, а только заставляет других делать. Если ему нужно что-то из базы достать или положить, он обращается к модели, надо что-то вывести, он использует вьюшку.
Это еще называется «тонкие контроллеры» — старайся писать как можно меньше кода в контроллере. Почему? Потому, что код в модели, если он правильно написан, можно использовать повторно, например вызвав этот код из другого места, а код в контроллере — нельзя.
В больших сложных приложениях часто еще бывает слой сервисов, который находится выше моделей и вызывает их методы. Ну например, регистрация пользователя подразумевает несколько действий — добавление пользователя в таблицу users, отправку письма, обновления всяких статистик — все это может делать сервис.
>>334149
Может даже не проверять. Просто получил данные, передал, получил результат валидации - отдал вюхе. Сам контролер данные не валидирует.
Антоны, смотрите какая офигенная идея: платные комментарии — http://tjournal.ru/paper/pay-per-comment
Я бы тоже так хотел. Если уж хейтеры и хаскеллисты хотят рассказать нам про фракталы неправильного дизайна, пусть хотя бы заплатят.
>>333950
Ок, всё понял, приму к сведению. While там остался от прошлой реализации, как-то забыл на foreach переделать, замотался уже под конец.
Изначально сам пытался сделать через array_keys, но что-то там не получилось, уж и не помню.
У меня вопрос по задачке про молодую динамично развивающуюся компанию. Как лучше высчитывать статистику по департаменту? Я как-то с кондачка сделал так, что при каждом устройстве/увольнении сотрудника изменяются соответствующие поля в объекте департамента (кофе, общая зарплата и т.д.).
Плюс в том, что если вообразить риаллайф использование скрипта, то увольнять/брать на работу будут, кмк, намного реже, чем запрашивать данные о департаменте.
Минус же в том, что если, к примеру, изменять ставку или количество выпитого кофе прямо в классе сотрудников, то надо отдельно вручную делать пересчет - как минимум, запустить соотв. метод в департаменте. А если делать сеттер этих полей в классе сотрудников, то надо его как-то связывать с соответствующим департаментом. Что плохая идея, насколько я понимаю.
Альтернатива - высчитывать этих величины при вызове методов getCoffee и т.п., но стоит убедиться, что действительно так лучше будет, перед тем как переделывать.
Что посоветуешь, ОП?
http://ideone.com/k8r7GE
массивы 2я задачка,что я делаю не так?
>>334207
Перечитай про for, он работает совсем не так, как ты от него ожидаешь.
>>334205
> Как лучше высчитывать статистику по департаменту? Я как-то с кондачка сделал так, что при каждом устройстве/увольнении сотрудника изменяются соответствующие поля в объекте департамента (кофе, общая зарплата и т.д.).
Ты увлекаешься преждевременной оптимизацией. Считать можно по-простому, сделав каждого сотрудника объектом, и просуммировав кофе/зарплату сотрудников департамента обычным циклом.
> Плюс в том, что если вообразить риаллайф использование скрипта, то увольнять/брать на работу будут, кмк, намного реже, чем запрашивать данные о департаменте.
Это и есть преждевременная оптимизация. Может, будут, а может и не будут. Может в компании никогда не будет больше 20 сотрудников. Может, нужен не идеальный код, а как можно быстрее написанный. Может тут такая текучка кадров, что люди больше полдня отработать не успевают. Лучше сначала сделать по-простому, аккуратно, но оставить возможность для оптимизации в будущем. В чем профит простого подхода? В том, что он быстрее пишется и с ним труднее сделать ошибку.
Это задача в первую очередь на понимание ООП, правильно определить объекты в задаче, их свойства и методы. А потом уже оптимизировать.
Ну если у тебя все уже оптимизировано и правильно считает, а код соответствует ООП-подходу, оставь так. Не разоптимизировать же обратно.
>>334207
Тут надо решать по другому. заводишь переменную с названием $числоОдноклассниковВышеАнона (по-английски естественно), присваиваешь ей 0. Затем циклом foreach проходишь по массиву, и если встречаешь одноклассника выше анона, увеличиваешь переменную на единицу.
Насчет for, ты все напутал. Смотри, в for пишется 3 выражения:
1) выражение, которое выполняется перед началом цикла. Обычно там присваивается начальное значение переменной (например, $x = 0).
У тебя там $number; Это выражение ничего не делает, оно берет значение переменной $number и ничего с ним не делает. Это то же самое, что написать
2+2;
PHP трудолюбиво сложит числа, но результат никуда не сохранит.
2) выражение, которое проверяется перед каждым шагом цикла и говорит, продолжать ли цикл (если оно истинно) или закончить
У тебя там $height > $anonHeight — продолжать выполнять цикл пока одна переменная больше другой. По видимому, это условие выполняется всегда и цикл тожде выполняется вечно.
3) выражение, которое выполняется после шага цикла. У тебя там $number ++ — увеличивается переменная $number.
В общем, да, цикл for ты понял как-то неправильно.Почитай тут например: http://www.php.su/learnphp/cs/?cycles#for
В общем, я тебе советую прочесть теорию, и для закрепления, решить дополнительную задачу. Задача такая: напиши программу, которая выводит таблицу умножения всех чисел от 1 до 9. Вывести можно в любом виде, можно красивой табличкой, если сложно то можно по простому, в 9 строчек:
1 × 1 = 1, 1 × 2 = 2, .... 1 × 9 = 9
2 × 1 = 2, 2 × 2 = 4, .... 2 × 9 = 18
...
9 × 1 = 9 .... 9× 9 = 81
Знак умножения (да, это не буква x, а знак умножения ×) можешь просто скопировать из этого поста.
http://ideone.com/LaM1Pp поправил
с доп заданием ничего лучше http://ideone.com/OgwiVD
не получилось;
>>334266
Задача про рост анона — все верно.
Задача про таблицу умножения:
- тут не нужен массив и foreach, используй цикл for который увеличивает переменную от 1 до 9
- чтобы сделать полную таблицу, надо использовать 2 вложенных друг в друга цикла, первый меняет допустим переменную $a от 1 до 9, второй для каждого значеия $a меняет $b от 1 до 9:
for ($a = 1; ....) {
for ($b = 1; ...) {
// пишем строчку $a * $b
}
}
>>334266
Алсо, сделай чтобы таблица умножения выводилась строчками по 9 значений (для этого надо правильно поставить echo "\n"; который выводит перевод строки)
Доброкунчик, подкинь материала годного по вот этой теме http://www.php.su/functions/?cat=pcntl , а так же по управление процессами в Unix для пхп-макак. Я здесь >>333705 спрашивал про крон. Теперь мне нужно писать демон. Все классы есть, все работает, но если я смотрю на исходный абстрактный класс демона - мне становиться грустно. Помоги развеять тоску-печаль.
>>334536
Ну для начала стоит проверить, понимаешь ли ты вообще как работают процессы в posix/linux, что такое сигналы, что такое fork и exec. Если не очень понимаешь, то для начала стоит почитать общую теорию:
http://www.k-max.name/linux/processy-v-linux/
http://www.opennet.ru/docs/RUS/lnx_process/
http://ru.wikipedia.org/wiki/Сигналы_(UNIX)
(если там что-то непонятно объяснено, можешь погуглить или задать тут вопрос).
Понимать общую теорию важно, так как функции pcntl ничего нового не представляют, а просто вызывают соответствующие функции ядра linux. Ну то есть pcntl_fork вызывает системный вызов fork(), pcntl_wait — вызывает wait() и так далее.
Ну и естественно, команды, которые упомянуты в статьях, надо вызывать из командной строки. Надеюсь, ей ты тоже умеешь пользоваться. Твой демон при отладке надо будет запускать из командной строки, так что без этого никак.
Плюс, если твой демон должен принимать соединения от других PHP-процессов, то тебе придется еще учиться работать с сокетами и придумывать протокол. Ну это отдельная интересная и обширная тема.
Ну и насчет кода — старайся все делать как можно проще, а не усложнять вещи. В частности, в демоне важны такие вещи:
- возможность блокировки, чтобы нельзя было запустить один и тот же демон 2 раза. Можно использовать блокирование с помощью создания файла с PID процесса (чтобы предыдущую копию можно было убить принудительно).
- возможно, стоит отслеживать сколько времени и памяти потребил скрипт. Ведь демон обычно обрабатывает большие массивы данных, и там легко отъесть много ресурсов и не заметить.
- стоит убедиться, что логгирование работает и любые варнинги и нотисы сохраняются в логи. Иначе демон может сидеть себе и тихонько портить базу неправильными значениями
- в некоторых случаях полезен еще флаг для тестирования, чтобы можно было запустить демон, но он ничего не писал в базу.
Еще возможно, надо будет научиться отцепляться от консоли (через posix_setsid() отсюда: http://www.php.net/manual/ru/ref.posix.php ) и наверно стоит написать init-скрипт, чтобы твой демон был полноценной службой и его например можно было бы запускать/останавливать/перезапускать стандартной командой и поставить на сервере в автозапуск, а не запускать ручками при каждой перезагрузке (поверь, это быстро надоест).
Ну ты вроде под Yii пишешь, так что делай как там принято, там есть класс для консольных команд.
vocaroo
аноны незнаю куда обратиться
пытаюсь разгадать одну херню
вот оригинал строчки:
Then HMAC-SHA512 is used to hash STRING1 with STRING2 giving us a 128 character hex string.
вот значения стрингов:
STRING1 = "3501:46fc85ae6e87cac1:3501"
STRING2 = "3501:c4d536307d28fc15:3501"
собственно вопросы:
для hmac sha512 я так понял обязательно нужен ключ для шифрования, так? и если хэш генерировать просто sha512 то получиться другое совершенно, так?
и я так понял что мы объединяем эти 2 строчки, так?
>>334557
Может быть одна из строк и есть ключ? Написано же
> hash STRING1 with STRING2
захешировать строку1 строкой2
>>334309
http://ideone.com/1yqSg1
пойду скушаю пирожок
Гуру PHP, ай нид хэлп, суть такова: внезапно, не помню после чего, перестали работать все регексы в проекте (возвращают false и отдают пустые массивы групп). Кодировка разбираемых текстов windows-1251, IDE – Eclipse.
Перед этим игрался с сессиями (но, в итоге, выпилил их использование) и написал пару методов, пишущих массивы в XML, но они никак не связаны с регулярками и контентом.
> echo "\n";
Рекомендую анонам в место этого использовать echo PHP_EOL;
>>334681
Чем оно лучше? \n работает везде, и пишется короче. То же самое и с DIRETORY_SEPARATOR: / работает везде и пишется короче.
>>334684
На маках другая последовательность символов. Да и просто, если язык даёт средства для автоматизации, то имхо предпочтительнее их использовать. Меня самого иногда ломает писать все эти длинные названия. По этому:
define(EOL, PHP_EOL);
define(DS, DIRETORY_SEPARATOR);
>>334688
Я конечно же хотел сказать.
> define('EOL', PHP_EOL);
> define('DS', DIRETORY_SEPARATOR);
>>334688
> На маках другая последовательность символов.
На маках используется \n для новой строки (как и в Линуксе), / как разделитель каталогов (как и в линуксе). В Windows используется \r\n но \n переводит строку в консоли, и виндовые функции понимают / как разделитель каталогов.
Вопрос, зачем тогда уродовать код этими константами?
Да, когда-то в маках были свои причуды, но с выходом Mac OS X там все стало как в линуксе, а вышла Mac OS X лет 10 назад.
Или ты знаешь какой-то реальный пример, когда / или \n не работабт на современных осях?
>>334708
Анончик, я таки считаю, что код уродуется отсутствием констант. И да, используя константы эти , я не вникаю в тонкости функционирования разных ОС, но я получаю гарантию, что код будет работать так как нужно и обеспечивается обратная совместимость. Так почему бы эти константы не использовать?
>>334737
Потому, что читать такой код тяжело. А если кто-то в будущем сделает свою ОС с нестандартными разделителями каталогов, то пусть заслуженно страдает.
>>334744
Анончик, я опять таки считаю, что сложнее читать
echo "\r\n";
чем
echo EOL;
Да и писать дольше.
По поводу новых разработок, твоя аргументация железная, лол. А если не разработает а модифицирует уже существующее популярное решение? Ты уверен, что в следующей версии макоси или винды не изменяться их стандарты?
Короче забей, Анон. Пиши как пишется, я никому ничего не навязываю.
>>334700
Я думаю, ты всё-таки хотел сказать
> define('EOL', PHP_EOL);
> define('DS', DIRECTORY_SEPARATOR);
Сдаю домашку.
http://viper-7.com/xdJKY9
Что-то переработал мальца, ну да ладно. ОП, особенно интересно было бы что-нибудь про эксепшны услышать. Я их там покидал немного, но не уверен, что в подходящих местах.
Еще - может что посоветуешь почитать про объектно-ориентированное проектирование? Так чтобы совсем энтри-левел, а то тема как я понимаю необъемная.
>>334754
\r не нужен же, я же написал, достаточно \n:
echo "Start\nWorking\nEnd\n"; — если строку разбить EOL и точками, то будет каша.
А пути как ты будешь писать?
$path = APP_DIR . "/data/files/file.txt";
Но я тут подумал и придумал решение. Можно сделать функцию, которая заменяет / на DS, а \n на EOL и писать нормально:
echo newlines("Start\nWork\nEnd\n");
$path = path(APP_DIR . "/data/file.txt");
>>334785
> может что посоветуешь почитать про объектно-ориентированное проектирование?
Ну конечно же Мэтт Зандстра — PHP. Объекты, шаблоны и методики программирования
Ну еще наверно можно почитать Thinking in Java (философия Java) но это книга про Яву, она огромная, так что если ты ее начнешь читать, мы тебя точно потеряем. Еще есть книга Мартин Фаулер «Patterns of Enterprise Application Architecture» — но она для тех, у кого есть опыт работы с реальными проектами, начинающий там половину не поймет. Но можешь посмотреть из любопытства. Именно в этой книге описываются разные паттерны, фабрики и прочие вещи.
Задачку сейчас тоже проверю.
>>334785
Табличка милая. Но, увы, старомодная. Таблицы в наше время выглядят так (меньше ненужных линий, промежутки между соседними ячейками и так достаточно большие):
http://viper-7.com/YZ5Pec
Не стоит выравнивать данные по центру ячеек. Надписи лучше выровнять влево, а числа −— вправо, чтобы их было легче сравнивать (я поленился это сделать). Задавать для таблицы высоту (height) нет смысла, так как высота определяется содержимым, а не тем, что ты задал. Ширину, наверно, лучше тоже не указывать, пусть определяется автоматиечски. Стоит указывать padding для ячеек, чтобы в любом случае оставались промежутки. Удобно в HTML-коде использовать теги thead, tbody, tfoot для выделения частей таблицы, чтобы можно было применить отдельные стили для подвала например.
А вот с ООП ты, конечно, напутал.
Company::__construct — да ну, зачем так сложно? Можно создавать пустую компанию, а добавлять департаменты просто через addDepartment(). Такой подход имеет смысл только если класс очень часто используется (и то, мне не нравятся такие функции, которые принимают на вход что угодно). Вряд ли у тебя будет создаваться компания в 30 разных местах в программе.
> is_a($d, 'Department')
Лучше использовать специальный оператор instanceof: $d instanceof Department
В мануале ( http://us1.php.net/is_a ) написано:
> Эта функция была помечена устаревшей в пользу оператора instanceof. Вызов данной функции вызовет предупреждение уровня E_STRICT
Читай мануал, это полезно.
>>334785
> throw new RuntimeException();
надо указывать причину: throw new RuntimeException("Element of array with key=$key, passed to ".METHOD." is not instance of class Department");
Желательно делать такие сообщения об ошибке, чтобы сразу было видно в чем проблема.
> public function addDepartment(Department $dep){
> if (is_a($dep, 'Department')) {
Это не нужно. У тебя стоит type hint в заголовке функции, PHP тебе не позволит передать что-то другое.
> try {
> ...
> throw new RuntimeException();
> }
> catch(Exception $e) {
> die("Компания должна состоять из департаментов!<br>".$e);
> }
Тогда проще сразу написать if (..) { die(); }. Исключения обычно выбрасывают и ловят в разных местах программы.
Плюс, die не нужен — PHP и так по умолчанию умирает при непойманном исключении.
Плюс, если ты ловишь исключения, то лови не все подряд, а только свои исключения: catch (RuntimeException $e)
>>334785
> $deps = array_filter($deps, function($d) { return is_a($d, 'Department'); });
Эта функция молча отбросит неправильные объекты, ничего не написав. А другие — выкидывают исключение. Неправильно. Лучше через foreach проверить.
> public function removeDepartment($dep) {
Не имеет никакого смысла передавать туда int (номер в массиве), так как непонятно, где этот номер взять? Ни одна функция его не возвращает. Передавай туда Department.
> public function getDepartment($id = 0) {
То же самое. Плюс, непонятно, почему 0-й депарамент такой особенный что возвращается по умолчанию.
> private function getterHelper($field) {
Нехорошо. Передавать половину названия метода нехорошо (например, ты не сможешь тогда поиском найти все места где вызывается getSomething, так как в коде написано просто 'Something'). Лучше сделай метод sumDepartmentsBy($callback), который вызывает переданную извне функцию на каждом департаменте:
$pay = $company->sumDepartmentsBy(function ($dep) { return $dep->getPay(); });
Чуть длиннее, но зато аккуратнее.
> $salaryMod = self::RANK_1;
Лучше массив вида (ранг => прибавка), не надо в константах хранить данные.
> public function hire($employee) {
> try {
> if (!is_a($employee, 'Employee')) throw new RuntimeException();
Короче так: public function hire(Employee $employee) {
> if ($isBoss && !$this->isBoss) {
Вот это особый кошмар. Это вообще понять невозможно, надо заменить на что-нибудь другое. Наример, так:
if ($this->isBoss) { .... }
> public function getPayPerPage() {
> return $this->payPerPage;
> }
Если написать return $this->getPay() / $this->getPages() то мы избавимся от неунжного поля payPerPage и сделаем код функции в 3 раза понятнее и очевиднее. Это нездоровая оптимизация, которая больше вреда приносит читабельности, чем пользы. Поделить 2 числа недолго, даже в PHP.
Для исключений лучше бы завести свой класс, а не юзать RuntimeException, так как в этом случае мы можем ловить только твои исключения.
В общем, исправь пока это, а потом проверим еще раз.
Вечер в хату, phpach.
Расскажи мне, пожалуйста, как на php эффективно работать с изображениями?
В чем суть: есть чб изображение, на изображении две метки(черные области 40х40px), Необходимо повернуть изображение так, что бы одна метка была над другой. Затем найти среднее значение цвета в некоторых заданых областях.
С первой задачей вообще не имею понятия как справится.
Со второй справляюсь простым проходом по всем пикселям и нахождением среднего арифметического, но это очень медленно.
Юзаю imagemagic
>>334785
Про исключения. История тут очень простая. До ООП ошибки обратаывались примерно так:
function bigFunction(&$error = '' /* для возврата текста ошибки */) {
$x = doSmth();
if ($x === false) {
$error = 'doSmth() failed';
return false;
}
$y = doSmth2();
if ($y === false) {
$error = 'doSmth2() failed';
return false;
}
return $x + $y;
}
function bigFunction() {
return doDomth() + doSmth2();
}
>>334797
Найти как-то эти метки, найти угол линии, проведенной между ними и повернуть на этот угол.
>>334786
Ого сколько всего! Спасибо. Буду править.
>>334793
>в мануале там написано
Ну да, а дальше написано:
>This function is no longer deprecated, and will therefore no longer throw E_STRICT warnings.
Но не суть, я быстро-быстро его проглядывал, до этих моментов даже не дошел. Впредь буду instanceof использовать.
Вообще, мануал не только читаю, но и задрачиваю. С помощью anki заучиваю основные функции с их параметрами, всякие моменты неочевидные вроде поведения self:: и static::.
Замечания по поводу вёрстки передам тян, она верстала :3
>>334805
До этого то я дошел.
Проход по всей линии в поиках черного пикселя-ну ооочень долго.
Да и как найти угол?
>>334807
> Вообще, мануал не только читаю, но и задрачиваю.
Не, наизусть учить не надо. Просто когда встречаешь новую функцию, просмотри страничку про нее, чтобы знать ее особенности. Постепенно все часто используемые функции будешь знать.
Единственный случай, когда стоит перечитать мануал — когда идешь на собеседование, например. Там любят спршивать дурацкие вопросы про то, чем отличается ++$x от $x++, про разницу операторов and и && или сработает ли if (array()) { ... } и if ("10" > "9") { ... }
>>334813
Ну, у меня хреновая память, так что мне это здорово помогает, плюс структурирует знания. Да и приятно не лазить каждый раз в мануал, когда строку надо обрезать или там регуляркой разделить. И времени не так уж много занимает.
Кстати, ответы на вопросы кажется знаю.
1. Преинкремент/постинкремент - сначала увеличивает, потом возвращает значение/сначала возвращает значение, потом увеличивает. Интересней было бы, если бы спросили что выдаст и как рассчитывается $a = 2; $a = $a += $a++;
2. Уровень приоритетности (главная разница - у 'and' он ниже чем у '=')
3. Вот тут не знаю, вроде да, т.к. массив хоть и пустой, но в списке falsy значений я его не припоминаю. Да и кажется пердолился как-то с тем, что выборка из БД была пустым массивом, а проверку if($res){} она проходила. Но не уверен.
4. Не сработает, сравнение строк идет по первому знаку (если не natcase)
Лол, меня возьмут жуниором?
Но я вообще чего спросить пришел. Нормально вообще выбрасывать исключение и не ловить его? Вроде где-то читал, что да, но при этом меня как-то коробит повторяющаяся дважды информация о нём при срабатывании.
И еще. Может кто-нибудь посоветовать халявный хостинг с php5.3+ ?
>>334815
Про пустой массив (он falsy) написано тут: http://www.php.net/manual/ru/language.types.boolean.php#language.types.boolean.casting
> Нормально вообще выбрасывать исключение и не ловить его?
Нормально. Если например тебе пытаются в функцию передать что-то левое, то зачем ловить такое исключение? Надо просто исправить код.
То же и с фатальными ошибками типа файл должен быть на диске, а его нет. Ну нет файла — извините, программа не работает.
Если речь идет о сайте, то конечно, придется поставить обработчик ошибок, чтобы при ошибке пользователи видели не белую страницу, а красивое сообщение о том, что скоро все исправится.
> коробит повторяющаяся дважды информация о нём при срабатывании.
Это странная особенность PHP, не обращай внимания (непойманное исключение вызывает фатальную ошибку и она выводит текст исключения второй раз, вроде так). В продакшене все равно ошибки пишутся только в логи, а на экран не выводятся.
> И еще. Может кто-нибудь посоветовать халявный хостинг с php5.3+ ?
Вроде один анон appFrog использовал. Еще есть host1free, но он легко может пару дней лежать.
>>334815
Алсо, для вопросов с собеседований, тут есть список правил преобразований: http://www.php.net/manual/ru/language.types.type-juggling.php в конце
И умопомрачающая таблица сравнения типов: http://www.php.net/manual/ru/types.comparisons.php (на тот случай если спросят как сравниваются массивы с помощью == и ===)
>>334820
А, понял, почему про массив напутал. Там то он был не пустой, а с другими массивами внутри, которые пустые.
Остальное принял к сведению.
>Передавать половину названия метода нехорошо (например, ты не сможешь тогда поиском найти все места где вызывается getSomething, так как в коде написано просто 'Something').
Вот про это не совсем понял, это же хелпер, он нужен только для внутренней структуры объекта. Там то там $vector->getSmth везде. Завтра перечитаю, сейчас уже голова мутная.
Остальное вроде поправил.
http://viper-7.com/TqJGRH
Аноны, поясните что тут делать? Как мне в субклассе изменить метод? Допустим родитель имеет метод: echo "Text";. Что писать, дабы субкласс изменял метод родителя на echo "text 2"? Я по-моему что-то упустил. Маны перелопатил и не нашел примера :( Только не серчайте на ньюфажину.
>>334828
Вот эта оптимизация опасна:
> $this->pay -= $employee->getSalary();
А что если между приемом на работу и увольнением у сотрудника изменился ранк или оклад? надо делать дополнительные проверки (ок, в учебной задаче нельзя менять ранг у сотрудника. Но в более реалистичной задаче наверняка понадобится. И тогда код всех тих проверок может стать запутанным и глючным).
> public function removeDepartment($name) {
Почему бы не передавать туда сам объект $department?
> Вот про это не совсем понял, это же хелпер, он нужен только для внутренней структуры объекта. Там то там $vector->getSmth везде. Завтра перечитаю, сейчас уже голова мутная.
Ну представь мы решили переименовать у класса Employee getPay в getSalary и делаем поиск по getPay (чтобы поменять название везде). 'Pay' мы не найдем и не переименуем.
>>334834
Определи в сабклассе новый метод с таким же именем.
>>334828
> $this->pay -= $employee->getSalary();
Я вспомнил еще одну потенциальную проблему: округление. В PHP дробные числа хранятся с ограниченной точностью. Если у работников дробная зарплата и ты добавишь человек 100, а потом всех уволишь, в итоге может остаться не 0, а например 0.0000001.
> Call to ". METHOD ." failed
Это было в моем примере, но я тут подумал, писать это не нужно. Если у тебя есть xdebug, то там и так выводится полный стек вызовов функций с именами и номерами строк, и в сообщениях об ошибке тоже есть номер строки.
> foreach($this->departments as $key → $dep) {
наверно => а не ->
> if ($dep->getName() == $dep->getName()) {
Это что?
> return $this->getterHelper('Pay');
Сделай хотя бы 'getPay', а то имя не будет вываливаться при поиске. Алсо getterHelper можно бы переименовать в sumBy
> if (!is_int($rank)) return false;
В конструкторе это не имеет никакого эффекта, как я понимаю, вернется все равно новый объект. Надо бросать эксепшен, так как false все равно не вернется. И даже если бы конструктор мог вернуть false, ты же все равно не проверяешь это.
public function __destruct() {
self::$employeesNumber--;
}
Неверно. Так может получиться 2 работника с одинаковыми номерами (если мы уничтожим не последнего, а какого-то другого). Также, объект можно клонировать (оператор clone) и копии уничтожить, тогда будет уничтожено 2 объекта и employeesNumber уменьшится на 2.
По этой причине, деструктор лучше вообще не использовать - он таит в себе столько подвохов, что легко наделать ошибок. деструктор используют обычно для освобождения выделяемых в конструкторе ресурсов, и то в 99% случаев он не нужен в PHP.
> protected $employeesCount = 0;
Это поле не нужно. Вызов count($this->employees) работает очень быстро, за O(1) так как в PHP в массиве хранится его длина. Эта твоя микрооптимизация то же самое, что заменять двойные кавыки на одинарные ради якобы ускорения программы.
Заметь, что удалив поле мы избавляемся и от ненужных более строк по его увеличению/уменьшению.
Если так хочется оптимизировать код, попробуй выоптимизировать цикл из fire() — там можно обойтись без перебора всего массива.
>>334842
>А что если между приемом на работу и увольнением у сотрудника изменился ранк или оклад? надо делать дополнительные проверки (ок, в учебной задаче нельзя менять ранг у сотрудника. Но в более реалистичной задаче наверняка понадобится. И тогда код всех тих проверок может стать запутанным и глючным).
Вот собственно примерно про это изначально и спрашивал, мне тоже показалось, что это порочный путь - слишком много подводных камней. Т.е. если надо изменить у какого-то сотрудника его параметры (повысить ранг например), или, например, в принципе модификаторы ранга поменять, то надо каждый раз всё пересчитывать заново. А ведь я читал у Макконелла про то, что микрооптимизации в ущерб очевидности кода надо оставить на потом, если производительности хватать не будет. Но одно дело прочитать, а совсем другое - напороться на это самому. Урок усвоен. :3
>Почему бы не передавать туда сам объект $department?
Вот не знаю, мне как-то это нелогично кажется. Это принятая практика? Тут проблема в том, что я не могу представить, как в риаллайф-приложении что-то подобное работает.
>Ну представь мы решили переименовать у класса Employee getPay в getSalary и делаем поиск по getPay (чтобы поменять название везде). 'Pay' мы не найдем и не переименуем.
Окей, ты наверное прав - при поддержке, когда уже не помнишь, что там и зачем автоматическому рефакторингу помешает. Буду иметь в виду на будущее.
>Я вспомнил еще одну потенциальную проблему: округление. В PHP дробные числа хранятся с ограниченной точностью. Если у работников дробная зарплата и ты добавишь человек 100, а потом всех уволишь, в итоге может остаться не 0, а например 0.0000001.
Ага, помнил про это пока писал, вроде там специальный класс есть для работы с валютой. Опять же, буду иметь в виду, но в учебном задании, да еще и на работу с ООП прежде всего, слегка overkill по-моему.
>Это было в моем примере, но я тут подумал, писать это не нужно. Если у тебя есть xdebug, то там и так выводится полный стек вызовов функций с именами и номерами строк, и в сообщениях об ошибке тоже есть номер строки.
Ага, тоже это заметил. Ну зато знаю теперь про магические константы в ООП, профит.
> if ($dep->getName() == $dep->getName()) {
> foreach($this->departments as $key → $dep) {
Ох лол. Невнимательность и суетливость - уже устал под вечер, хотелось поскорее расправиться. Гнилая отмаза, да.
Вообще мне кажется, что уже даже на таком маленьком "приложении" можно поиметь профиты от автоматического тестирования. Тесты бы такие косячки не пропустили. А второй (вроде должен с ошибкой синтаксиса вываливаться) я так и вовсе у себя исправил, а на вайпера залить забыл.
>По этой причине, деструктор лучше вообще не использовать - он таит в себе столько подвохов, что легко наделать ошибок. деструктор используют обычно для освобождения выделяемых в конструкторе ресурсов, и то в 99% случаев он не нужен в PHP.
Принял к сведению. Как тогда лучше айдишники генерировать? Мне приходит в голову только с помощью mt_rand и проверять при создании нового, что такого еще нет. Но это наверное не совсем верная мысль.
Кстати, в каких случаях стоит использовать деструктор для освобождения ресурсов? Например, насчет circular references не особо понятно - вроде есть специальный гарбаж коллектор, а вроде он и не всегда включен бывает.
>Если так хочется оптимизировать код, попробуй выоптимизировать цикл из fire() — там можно обойтись без перебора всего массива.
Если передавать объект Employee и использовать array_keys или array_search? Но в этом же случае емнип массив всё равно будет перебираться, просто за кадром.
Вообще, ОП, огромное тебе спасибо. Многие косяки из тех, что ты подмечаешь, только видя код со стороны и обладая значительным опытом можно заметить, очень рад, что есть кому попинать и не давать расслабляться.
>>334939
>> Почему бы не передавать туда сам объект $department?
> Вот не знаю, мне как-то это нелогично кажется. Это принятая практика? Тут проблема в том, что я не могу представить, как в риаллайф-приложении что-то подобное работает.
Ну возьмем риаллайф-приложение: DOM в браузере. DOM — это дерево всех узлов (соответствующим HTML-тегам) на странице. DOM есть и в PHP в виде расширения. Там для удаления дочернего узла используется такой код:
$parentNode->removeChild($childNode); // http://php.net/manual/ru/domnode.removechild.php
То есть родителю передается объект-ребенок, которого надо удалить. Хотя, в такой ситуации можно конечно было бы сразу сделать метод remove у ребенка:
$childNode->remove();
Но почему-то так не сделали (так сделали в jQuery, которая является оберткой над DOM).
В общем, первый вариант - передавать объект или сделать метод remove у самого объекта. Второй вариат — передавать в removeDepartment id департамента, если они уникальные. Но для получения id тебе скорее всего надо сначала как-то найти сам департамент, и вызывать у него getId() — так что, передавать сразу объект выходит короче. Передача id обычно используется во всяких удаленных интерфейсах, например, в каком-нибудь сетевом API, чтобы не гонять объект туда-сюда.
> Как тогда лучше айдишники генерировать?
Так как у тебя, но никогда не убавлять self::$employeeNumber, только увеличивать. Тогда повторов не будет. По такому принципу работает AUTO_INCREMENT в MySQL.
> вроде там специальный класс есть для работы с валютой
При работе с валютой обычно используют числа фиксированной точности, с заранее заданным числом знаков после запятой (в MySQL это тип DECIMAL например). Также, есть расширение BCMath для работы с числами произвольной точности.
> Кстати, в каких случаях стоит использовать деструктор для освобождения ресурсов? Например, насчет circular references не особо понятно - вроде есть специальный гарбаж коллектор, а вроде он и не всегда включен бывает.
Ненужные объекты PHP (на которые больше нет живых ссылок) должны по идее всегда собираться и удаляться сами. Если кто-то отключил GC — он делает это на свой страх и риск и это его проблема, если что-то не очистится. Специально учитывать это в коде не надо, если что-то не освобождается по вине PHP — пиши им баг-репорт, пусть исправляют.
Ресурсы - имеются в виду внешние относительно PHP ресурсы. Например, если мы создали в конструкторе временный файл, то можно в деструкторе его удалять. И то, это какой-то сомнительный код, конечно получается, так как PHP вполне может упасть так, что деструкторы вызваны не будут. В линуксе обычно делают по-другому, создают и открывают временный файл и сразу же делают ему unlink: в этом случае файл автоматически удалится операционной системой, как только его закроют (в том числе при падении программы). Но под виндой это уже не работает, там файл удаляется сразу.
Я в реальных проектах особо применения деструкторов не видел. Открытые файлы закрываются сами, соединения тоже, незакомиченные транзакции в базе откатываются при разрыве соединения, практически всегда все это происходит автоматически. Единственный раз, когда я видел использование деструктора, он удалял временные файлы, причем из-за этого по моему как раз возникал какой-то баг.
>> Если так хочется оптимизировать код, попробуй выоптимизировать цикл из fire() — там можно обойтись без перебора всего массива.
> Если передавать объект Employee и использовать array_keys или array_search?
Нет. Это все равно будет O(N). Чтобы было O(1), надо в массиве employees использовать id в качестве ключа и удалять работника тогда можно через unset($employees[$id]).
> Вообще мне кажется, что уже даже на таком маленьком "приложении" можно поиметь профиты от автоматического тестирования.
Верно, это приложение, которое вещь в себе не лезет никуда наружу, и оно хорошо тестируется. Реальный код, увы, не всегда является «вещью в себе». Если хочешь заморочиться с тестированием, то хорошо бы установить например phpUnit и писать тесты на нем, так как это уже готовый тестовый фреймворк.
>>334941
Для этого мы и решаем задачки. Косяки, да, подмечаю, так как ООП не самая простая вещь и многие в нем путаются, а знать его надо обязательно (и есть книги/курсы, где его не изучают, что печально).
Как грамотнее устанавливать JS-события на множество однотипных элементов, которые формируются на php?
1. HTML внутри php-цикла:
<?php foreach($row as $value) {
//формируем большущую табличку с кнопками, например такими:
?>
<span class='delete' onclick='deleteRow()'></span> <!--элемент интерфейса, удаляющий ряд в таблице-->
<?php
}
?>
2. На чистом JS, как-то так:
<script>
var spans=document.getElementByClassName('delete');
var total=spans.length;
for (var i=0;i<total;i++) {
spans.onclick=deleteRow;
}
</script>
3. На jQuery, как-то так
$(function() {
$('.delete').click(function() {
deleteRow();
})
})
tags: Производительность, говнокод.
>>334971
Вариант с onclick="..." — ОК (так любит делать например вконтакте)
Вариант 2 и 3 с $('.delete').click — отстой, так как ты сначала ищешь кучу элменетов и ставишь кучу обработчиков. А если бы автор кода вместо изучения jQuery изучил яваскрипт и DOM ( в чудесном учебнике http://learn.javascript.ru/event-delegation ) то узнал бы, что события всплывают и можно один поставить обработчик на родительский элемент (и да, в этом случае динамиечски добавляемые элементы тоже будут работать).
Так что либо прописывай onclick="" либо ставь один обработчик на родителя. И еще, я бы советовал использовать для кнопки button: он гораздо удобнее, чем span, плюс он выделяется табом, не разрешает выделять на нем текст и вообще ведет себя как настоящая кнопка.
>>334971
Насчет jQuery, если используешь его, то и обработчик удобно ставить с помощью него: $('#table').on('click', '.delete-row', function (e) {
...
}); — по моему в новом jQ это делается так. Строчка '.delete-row' пропускает только события, возникшие на кнопке, а не в любом месте таблицы.
>>334973
Спасибо, пожалуй, c onclick='' проще всего сделать. А если несколько функций надо повесить, решение со вспомогательной функцией покатит?
onclick='temp()' где
function temp() {
deleteRow();
recount();
ajax();
}
А то onclick='deleteRow(); recount(); ajax();' как-то вырвиглазно выглядит, хотя работает. Про addEventListener, attachEvent читал, там ад с кроссбраузерностью, передачей this и аргументов, не хотеть.
И вдогонку: есть ли смысл дополнительно прописывать id для инпута чтобы брать его в JS с помощью getElementById(), если его можно взять getElementsByName()[0]. По айди вроде как быстрее, но в данном случае имя на форме уникально и всего одно.
>>334980
> Про addEventListener, attachEvent читал, там ад с кроссбраузерностью, передачей this и аргументов, не хотеть.
jQuery кое-что в этом плане исправляет и приводит события к единообразному виду. Алсо если без jQuery, ада нет, есть код для w3с и для IE, всего 2 варианта:
function myCallback(e) {
var ev = e || window.event;
var target = ev.target || ev.srcElement;
...
}
Этот код уже решает половину проблемы.
> решение со вспомогательной функцией покатит?
Да только название сделай нормальное, желательно со своим префиксом чтобы не пересеклось с другой функцией.
> И вдогонку: есть ли смысл дополнительно прописывать id для инпута чтобы брать его в JS с помощью getElementById(), если его можно взять getElementsByName()[0]
Есть, наверно. В jQuery тогда тоже можно писать $('#abc') что и быстрее и короче. Чтобы не было проблем с дублирующимися id (например, 2 формы на странице), используй префиксы: #register-email, #login-email
Объясните мне пожалуйста, зачем нужны абстрактные классы? http://www.php.net/manual/ru/language.oop5.abstract.php <-- здесь вообще не говорится зачем они нужны (а нахуя?) а вот здесь первый ответ вроде 27 человек оценили, но я ничего не понял. Читал ответы на stackoverflow и на askdev но всё равно не пойму зачем их использовать. Может кто-то попытается объяснить на пальцах? Помогите анончики, вы последняя надежда.
У анона выпало 6 и 6
У компьютера 6 и 6
Сума в анона 12
Сума у компьютера 12
2 дабла!
>>335033
Да, это редко бывает.
>>335025
Абстрактный класс — это класс, объект которого нельзя (или нет смысла) создать. Обычно а.к. используется в качестве базового класса, от которого наследуются уже не-абстрактные (=конкретные) классы.
Если ты программист, и ты хочешь запретить создавать объекты класса (или ты в общем-то не против, но смысла создавать их нету), ставь ему abstract. Плюс, ты можешь натыкать абстрактных методов, и классы-наследники будут обязаны их реализовать.
Пример — программа про ООО Вектор: http://viper-7.com/TqJGRH — здесь класс Employee просто обязан быть абстрактным (но это почему-то не сделано), так как надо создавать один из его наследников.
>>335038
Да, и судя по виду местности, из нашей страны.
>>335025
Большая часть всех этих непонятных штук в программировании имеет отношение к повторному использованию кода.
И абстрактные классы - не исключение.
Причин делать класс именно абстрактным может быть несколько.
Например - требование ко всем наследникам реализовать определённый (полиморфный) метод, который невозможно реализовать в данном классе, но который используется другими методами, уже реализованными в данном классе (это может быть достаточно хитро для начинающего).
Тогда абстрактный класс включает только заголовок такого метода (методов), т.е. только интерфейс, но не реализацию.
Или, класс может быть просто абстрактным по определению, т.е. создание его объектов не имеет смысла. Но, при этом он реализует кучу функционала, необходимого наследникам. Например, Creature в какой-нибудь игре. Тогда его делают абстрактным просто чтобы гарантировать невозможность создания его экземпляров.
Аноны, а двач ведь схороняет страницы в html, чтобы грузить быстрее и независимо от базы, так? У двача все просто, можно разложить треды по доскам (в папках) и радоваться жизни. А если сайт, например, о шарах. Шары бывают большие, средние и маленькие, а ещё красные, чёрные, синие и коричневые. Под цвет и размер есть две разные менюшки, сделать размер или цвет главным параметром (чтобы вложить в него другие) нельзя, так как надо в любой момент иметь возможность вывести все красные шары или все маленькие или все большие коричневые. Как разложить их? Дублировать две вложенные структуры? Это наверное быдлокод и может усложнить жизнь раскручивающему. Может какие-то номера дать отдельным шарам (образно, страниц с описанием товара шар, статьям о шарах, контактных данных шаров) и сохранять их по номерам, а в структуре хранить только основные страницы каталога?
>>335120
Не изобретай велосипедов, а возьми готовую CMS, например, Друпал, Вордпресс, и вбей свои шары в нее. Выйдет гораздо быстрее, кода писать почти не надо, только верстку.
Параметры шара в WP можно сделать тегами, тогда одной статье можно назначить 2 тега — «красные шары» и «большие шары». Или же, если рчь о Друпале, можно сделать у шара 2 категории через CCK — «цвет» и «размер». Ну и менюшки после этого можно прикрутить любые.
Заметь, что используя CMS ты получаешь уже готовый код и админку, из которой в любой момент можно добавлять, удалять. редактировать описания шаров. И это все не написав ни строчки кода. А сам ты угробишь на это неделю-две и получишь кучу быдлокода без админки.
> чтобы грузить быстрее и независимо от базы, так?
База есть на любом хостинге за 50 рублей в месяц. Плюс, такой подход, как я понимаю, создает огромную нагрузку на диск при активном постинге.
>>335120
А, если ты эти шары собрался продавать, то бери готовый движок интернет-магазина.
>>335038
Среднетян из хохлостана.
http://lisavasya.deviantart.com/
>>335120
>грузить быстрее и независимо от базы
Либо отправить запрос в базу и узнать имя html документа, где эти данные лежат в файловой системе, а затем отправить клиенту 302-й редирект (не 301-й, т.к. это не жёсткий редирект, а простое сообщение о том, что данные физически лежат в другом месте), чтобы клиент их забрал -
- либо никак.
>>335166
Что за наркоманство ты пишешь? Чтобы ускорить сайт на тяжелой CMS или вордпрессе, не нужны никакие самописные кривые системы на файлах.
Ставишь нгинкс, на нкинкс ставишь кеширование в мемкеш (к примеру), дописываешь костыль чтобы при постинге коммента/правке в админке кеш чистился, и твой сайт легко будет такой хайлоад держать, который самоделкиным с файлами и не снился.
>>335169
Дорого. У меня хостинг в "Зеноне", они сами зеркалируют сколько угодно файлов на какое-то количество зеркал, и отдают файлы с них. А чтобы поставить nginx и memcahce, надо... надо... иметь хоть какой-то доход от сайта, наверное! А у меня его нету.
>>335172
И твое время на написание кривых неуправляемых велосипедов стоит меньше, чем нормальный хостинг? Ну ок, это хорошо для тебя, но я хочу предупредить, что для 99% анонов совет писать велосипеды только вреден и им с точки зрения затрат проще поставить готовую CMS и мемкеш.
Если тебе нужен статический сайт на файлах без БД, не надо писать код, ты можешь сделать так:
- найти и заюзать программу-генератор статических сайтов (вроде бы фронтпейдж так умеет, рисуешь в нем сайт а он генерирует HTML)
- сделать на локалхосте сайт на любой CMS, какой-нибудь программой типа супер-пупер-сайт-даунлоадер скачать его в папку в виде кучи HTML файлов и их выложить на хостинг. При обновлении повторить.
>>335172
Насчет генераторов сайтов: тут их много: http://habrahabr.ru/post/93499/
>>335216
Аноны предпочитают нагрузку на память нагрузке на диск (даже те, кто предпочитает нагрузку на диск нагрузке на базу), такие дела.
Что можешь посоветовать в обучение в дальнейшим ?
Имеется основная база(без ООП) со знаниемя mysql, etc.
>>335222
ООП и фреймворки, они везде нужны.
Также, научиться HTML/CSS/JS, не на уровне крутого фронтендщика, а на базовом, уметь что-то поправить.
>>335216
Тогда используй генератор статических сайтов или разверни сайт на локалхосте и сохрани его в HTML. И эти файлы копируй на хостинг — нагрузка будет только на диск, хостить можно хоть на юкозе, PHP не нужен.
Если @ - это плохо, то как можно изящно заменить
<input type='text' value="<?=@$_POST['foo']>">
в форме, так чтобы если валидация не пройдена значения там сохранялись?
Или в готовом варианте просто выключить эти нотисы?
>>335257
Использовать @ — плохо
Выключать нотисы — дважды плохо
Правильное решение: сделай функцию post('foo', 'defaultValue') или сразу post('foo')
Алсо не забудь про экранирование:
<?= htmlspecialchars(post('foo')) ?>
Паста про экранирование и XSS: https://gist.github.com/anonymous/52adda0113428b274c64
На словах ты Лев Толстой
не могу понять как решать эту задачку,halp
Задачка про школьника и айфон. Скажем, я выполнил задание, но решил пойти дальше и подсчитать сколько школьнику пришлось переплатить. Т.е. надо посчитать разницу между $totalPayment и суммой заёма = 40000. Я не смог придумать ничего умнее, чем создать новую переменную $loan и присвоить ей значение 40000 (4-ая строчка). А как можно это сделать не засоряя пространство имен лишней переменной? В каждой итерации цикла мы увеличиваем $currentBalance, а как можно обратиться к первоначальному значению, не создавая новую переменную?
http://codepad.org/1oi7ksFd
Задачка про школьника и айфон. Скажем, я выполнил задание, но решил пойти дальше и подсчитать сколько школьнику пришлось переплатить. Т.е. надо посчитать разницу между $totalPayment и суммой заёма = 40000. Я не смог придумать ничего умнее, чем создать новую переменную $loan и присвоить ей значение 40000 (4-ая строчка). А как можно это сделать не засоряя пространство имен лишней переменной? В каждой итерации цикла мы увеличиваем $creditBalance, а как можно обратиться к первоначальному значению, не создавая новую переменную?
http://codepad.org/1oi7ksFd
http://codepad.org/5rIZvMMa
Правильно ли я использую префиксный декремент? Или он тут не нужен? Ведь сначала увеличивается сумма на счету, а потом выполняется инкрементирование $i++. В следующий раз условие цикла не выполняется, но $i то уже увеличилось на единицу.
Анон, а научи меня в mysql! Всегда пользовался двумя типами полей, никогда не заморачивался с индексами, транзакциями, связями таблиц, что там еще есть страшного, вообще не знаю, зачем нужна половина настроек phpmyadmin - тем более не представляю, логические поля делаю целочисленными с длиной 1, с перечислениями вообще не разбирался, с типами таблиц тем более. Какая есть годнота на русском языке по этой теме? Чтобы от и до желательно, как, где, почему, а главное, что это даст (желательно иметь подробную книгу с разбором принципов, может даже реляционной модели вообще, но при этом чтобы был также упор на объяснение, зачем это все нужно и что это нам даст. Это - каждый конкретный случай).
>>335327
какая няшка, я бы проткнул ее своей пикой. Только современная заколка и низ штанов в ноль портит впечатление. Косплеит кого-то? И еще вопрос: меч пластмассовый? Если нет, то как она его держит так легко своей хлипкой ручкой, если он весит не меньше грамм 900, а балансом ему, по всей видимости, выступает гарда?
>>335318
Берешь первый массив слов. C помощью mt_rand генерируешь число от 0 до (число элементов - 1). Потом берешь элемент с индексом, равным этому числу и таким образом получаешь случайное слово из массива.
Так же делаешь и с остальными массивами.
Потом из слов собираешь строчки.
>>335327
> А как можно это сделать не засоряя пространство имен лишней переменной?
Одна переменная ничего не решает. Так что засоряй, и не заморачивайся. Вместо того, чтобы думать как убрать одну переменную, лучше думать, как убрать десяток лишних строчек из программы.
Тем более, у тебя программа на 40 строчек. «Засорение пространства имен» опасно в огромных программах, так как можно случайно сделать новую переменную, которая совпадет с какой-то уже существующей и перезаписать ее значение, а у тебя такой проблемы нет.
Код как-то выглядит усложненно. Я проверил, программа считает все верно, но код лучше упростить:
switch ... case из 2 вариатов можно заменить if или, что еще короче, тернарным оператором ( http://php.net/manual/ru/language.operators.comparison.php ):
echo ($years != 1) ? "$years лет" : "$years год";
switch используют когда вариантов не 2, а много.
Замечу, что для числа 21 твой код напишет «21 лет», а по-русски будет «21 год».
> if ( floor($month/12) >= 1) {
Можно написать if ($years >= 1) зачем копипастить?
> $last = (($creditBalance * $percent + $servicePayment) < $monthlyPayment);
> $lastPayment = $creditBalance * $percent + $servicePayment;
> $creditBalance = ( $creditBalance * $percent ) + $servicePayment - $monthlyPayment;
Это копипаста, копипаста — зло. Лучше бы ты один раз посчитал и положил в переменную, а не копипастил формулы.
Но вообще, неплохо сделано, программа считает, да еще и числа пытается склонять.
>>335331
Нехорошо, так как приходиится тупить и вспоминать, в ккаком порядке это считается. Надо писать так, чтобы порядок был очевиден:
$i--;
$age += $i;
Код должен быть читабельным и понятным в первую очередь, чтобы кто-то мог взглянуть и за секунду понять как он работает, а не расшифровывать его.
> В следующий раз условие цикла не выполняется, но $i то уже увеличилось на единицу.
Можно просто поставить $age++ внутрь цикла — тогда возраст будет расти только пока работает цикл.
Алсо, выравнивание у тебя как-то разъехалось, все криво. Попробуй писать код в редакторе типа Sublime или Notepad++ или ideone.com, там при переходе на новую строку пробелы не теряются. Или пропускай код через phpformatter.com, вот что получается:
<?php
/*W5.2 Некто кладет в банк 10000 р. Банк начисляет 10% годовых (то есть, каждый год на счету
становится на 10% больше, чем в прошлом году). Напиши программу, считающую, через сколько лет
в банке будет миллион? Сколько лет будет этому некто? Доживет ли некто до этого дня, если сегодня
ему 16 лет? */
$dep = 10000;
$rate = 1.1;
$age = 16;
for ($i = 1; $dep < 1000000; $i++) {
$dep *= $rate;
}
$age += --$i;
echo "$i years passed. \n";
if ($age <= 100) {
echo "The man will be $age - He'll probably be still alive.";
} else {
echo "The man would be $age - Most likely he won't make it...";
}
?>
>>335336
На русском мало что есть. Есть вот это:
http://www.mysql.ru/docs/
http://www.mysql.ru/docs/mysql-man-4.0-ru/
— но там все не очень новое. Но транзакции и индексы там есть.
Индексы нужны ради повышения производительности. Поиск записи по индексы — быстрый, без индекса MySQL перебирает всю таблицу. Джойнить таблицы без индексов — вообще кошмар.
Про оптимизацию и производительность можно почитать тут: https://www.google.ru/search?client=opera&rls=en-GB&q=mysql+exmplain+%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D1%8B&sourceid=opera&ie=utf-8&oe=utf-8&channel=suggest
Транзакции нужны ради обеспечения целостности. Пример — банк, Вася переводит деньги Пете, банк вычел деньги с Васиного счета, и в этот момент отключилось питание. Чтобы деньги не исчезли, нужно было использовать транзакцию. Подробнее:
http://ru.wikipedia.org/wiki/Транзакция_(информатика)
http://habrahabr.ru/post/135217/
http://www.mysql.ru/docs/man/ANSI_diff_Transactions.html
>>335336
Насчет типов полей и вещей, которые стоит знать:
ENUM — позволяет задать значением поля только один из нескольких вариантов. Профит: защищает от ошибок (если случайно попытаться вставить неправиьное значение), плюс сразу видно какие значения могут быть. Пример использования: статус заказа в мазазине:
status ENUM('new', 'paid', 'cancelled', 'sent', 'completed') NOT NULL
DECIMAL — тип с фиксированной точностью. В отличие от FLOAT/DOUBLE, которые приближенные и могут терять знаки после запятой, DECIMAL хранит заданное число знаков. Используется например, для хранения суммы денег.
DATE, TIME, DATETIME, TIMESTAMP — хранят дату/время.
NULL — в БД NULL значит «неизвестно». Например, возраст пользователя неизвестен. Соответственно, все операции с NULL это учитывают: NULL + 5 тоже дает в итоге NULL (5 + неизвестное число дает неизвестное число), сравнение (NULL == NULL) возвращает ложь, чтобы проеврить равно ли поле NULL надо использовать ISNULL(x). http://ru.wikipedia.org/wiki/NULL_(SQL)
> логические поля делаю целочисленными с длиной 1
В MySQL по моему есть BOOL, но он равносилен TINYINT
VARCHAR(N), TEXT, MEDIUMTEXT, LONGTEXT — разница в том, что в VARCHAR органичение на N симовов и он хранится в ряду с другими данными,а у TEXT — 65535 символов и он хранится отдельно. MEDIUMTEXT и LONGTEXT позволяют хранить больше 65535 символов.
Связи таблиц — полезная вещь. Не позволяют, например, удалить запись на которую ссылкаются другие записи (или же позволяют удалить, но при этом удалить и все ссылающиеся записи). Неплохо защищают от ошибок.
В общем, попробуй прочесть мануал и посмотри, что из перечисленного можно использовать.
Про реляционные отношения, надо в первую очередь разобраться с нормализацией ( http://club.shelek.ru/viewart.php?id=311 ) и денормализацией, отношениями один-к-одному, один-ко-многим, многие-ко-многим. Нормализация нужна для устранения избыточности, денормализация — прием, применяемый ради повышения производительности.
Ну и наконец, есть еще такая тема, как хранение иерархических данных в БД (например, категории товаров или древовидные комментарии). По ней у меня есть паста: https://gist.github.com/anonymous/005304b65600a3889ee4
>>335336
А, и еще есть такая вещь как UNIQUE INDEX. С помощью уникального индекса можно запретить вставлять в таблицу одинаковые значения (например, 2 пользователей с одинаковым логином).
Аноны. Вопрос. Как сделать так - Echo запрос ввода данных, пауза, пока данные не введут и не нажмут Enter, запрос других данных, снова пауза пока не введут и не нажмут Enter. Так около 4х раз, И УЖЕ ПОСЛЕ - выполнение скрипта дальше. Помогите?
Это все реализовываю в виде консольного скрипта.
Можно сделать с формами, но мне так не нужно.
доброанон, помоги
Почему может не проходить запрос вида
UPDATE table SET param1='$param1', time=$time WHERE param2='$param2' AND param3='$param3'
пробовал играться со скобками у AND, пробовал ставить-убирать кавычки - толку никакого, запрос просто не проходит, при этом ошибки не выдается никакой. Названия таблицы, полей правильные.
Попытка спросить о причинах ошибки у mysql_error($result) ничем не заканчивается, он говорит, что ему передано логическое значение, когда он хотел получить ресурс. Попытка распечатать $result дает нихера. Перед этим с той же базой и почти теми же параметрами SELECT проходит спокойно и без ошибок. Практически такой же код с UPDATE раньше с другой базой тоже работал прекрасно.
>>335388
Очень просто.
1) Открываем поток стандартного ввода (stdin, то есть поток данных с клавиатуры) на чтение и сохраняем полученный дескриптор потока в $fd:
$fd = fopen('php://stdin', 'r');
Мануал: http://php.net/manual/en/function.fopen.php
http://www.php.net/manual/ru/wrappers.php.php
http://php.net/manual/ru/features.commandline.php
2) читаем из открытого потока одну строку (любые символы + Enter):
$line = fgets($fd);
В $line будет введенная строка + символ \n который можно отрезать с помощью rtrim().
3) Наверняка тебе захочется проверять то, что ввел пользователь, и просить ввести повторно при ошибке. Ок, используй цикл do ... while(). Код думаю ты и сам можешь написать.
4) Наверняка, тебе захочется улучшить возможности ввода. Например, сделать автодополнение по нажатию Tab, чтобы работали стрелки и редактирование или историю с доставанием ранее введенных данных стрелками ↑↓ и оиском по Ctrl + R как в настоящей командой строке. Ну что, любители windows тут, увы, проходят мимо, а любители linux или mac могут использовать расширение Readline: http://www.php.net/manual/ru/ref.readline.php
>>335400
Наконец, расскажу еще про одну штуку, которая есть в линуксе. Допустим, тебе попалась консольная программа, которая не поддерживает редактирование командной строки и историю команд. Печалька. Не беда, можно запустить ее через команду rlwrap, которая добавит эти возможности.
> Почему может не проходить запрос вида
Включи display_errors, если это не боевой сервер, если боевой, ищи сообщение об ошибке в логах.
> mysql_error($result) ничем не заканчивается
Туда надо передавать не $result, а соединение $conn, которое возвращает mysql_conneect:
$conn = mysql_connect(....)
Или, можно вообще ничего не передавать, тогда она сама возьмет текущее соединение.
Алсо, дам тебе еще 2 совета:
1) Функции mysql_* устарели много лет назад. Не знаю, где ты их умудрился откопать и выучить, сейчас все работают с базой через PDO
2) Нельзя подставлять переменные прямо в запрос, это веет к инъекциям. Правильно — использовать плейсхолдеры в PDO или библиотеке для рбаоты с БД:
$title = 'PHP%';
$author = 'Bobi%';
// query
$sql = "SELECT * FROM books WHERE title like :title AND author like :author ";
$q = $conn->prepare($sql);
$q->execute(array(':author'=>$author,
':title'=>$title));
>>335363
не пугайте народ
Enum внутри все равно преобразуется либо к tinyint либо к int.
Даты настолько разные, что ОБЯзательно читать мануал по каждой, т.к. скорость поиска разница в сотни раз.
И ОБЯзательно помнить, что поле NULL занимает дополнительный байт и при обработке полей с нулами применяются дополнительные просчеты.
varchar запомните что это ДИНАМИЧЕское поле, которое хранит вначале байт длинны, это очень сильно отразится на больших обьемах поиском в этих полях, поля постоянной длины намного быстрей работают.
Лучше все запомните пару важный правил
1) стремиться делать выборки только по индексу и только по числу (инт, бигинт)
2) избегайте Null-ов и динамических полей насколько возможно
>>335398
Ты даешь дурные и неграмотные советы. Не слушайте этого анона.
> Enum внутри все равно преобразуется либо к tinyint либо к int.
Ну и круто, хранится он компактно числом, а в таблице мы видим понятные вещи вроде new|paid|cancelled, плюс MySQL не позволяет вставлять левые значения. Надо быть дурачком, чтобы вместо ENUM лепить какие-то свои кривые велосипеды.
> Даты настолько разные, что ОБЯзательно читать мануал по каждой, т.к. скорость поиска разница в сотни раз.
Это бред, насчет сотен раз. Даты стоит хранить как DATETIME хотя бы потому, что в этом случае они выводятся в нормальном виде и можно писать NOW() + INTERVAL 7 DAYS.
Насчет того, в каком виде хранится, написано тут: http://dev.mysql.com/doc/internals/en/date-and-time-data-type-representation.html
> TIMESTAMP
> 4 bytes, little endian
> DATETIME
> 8 bytes, little endian
Вполне норм. Какой смысл вместо стандартного способа хранения дат/времени придумывать свои кривые велосипеды? Так делают только школьники, которым в видеокурсе не рассказали про эти типы.
> это очень сильно отразится на больших обьемах поиском в этих полях, поля постоянной длины намного быстрей работают.
Для поиска нужен индекс, а индексу пофиг varchar у тебя или char, верно? Плюс, использование char увеличивает объем таблицы, так как если у тебя поле 200 символов, то эти 200 * (размер символа) байт хранятся в любом случае, таблица становится огромной, надо больше памяти, дисковых операций, и в итоге все может наоборот работать медленнее. Потому твой совет неграмотный. В одних ситуациях лучше одно, в других — другое.
Алсо, я еще видел, некоторые используют хеши для ускорения поиска по строке.
> И ОБЯзательно помнить, что поле NULL занимает дополнительный байт и при обработке полей с нулами применяются дополнительные просчеты.
И пофиг. Это ничего не меняет. База тормозит не из-за «дополнительных просчетов», а из-за дисковых операций.
> Лучше все запомните пару важный правил
> 1) стремиться делать выборки только по индексу и только по числу (инт, бигинт)
> 2) избегайте Null-ов и динамических полей насколько возможно
Лучше изучить, как работают индексы и научиться пользоваться командой EXPLAIN, а не применять такие советы бездумно. Научиться смотреть статистику использования разных буферов и делать выводы.
>>335415
ооо вижу ты совсем не знаком с приличными проектами на мускуле,
где ты увидел что предлагают использовать свои форматы енума?
чет я вижу только предложения использовать tinyint как вариант и не более...
С датами сразу вижу ты не работал, когда наберешь хотябы 5-10 миллиончиков, узнаешь насколько DATETIME медленней TIMESTAMP-а,
и опять же ГДЕ вы ВИДИТЕ изобретателя велосипеда?
было только предложено прочитать какая именно дата подойдет именно в вашем случае.
Для начинающих нулы может и пофиг, потом когда вы наберете только истории хотябы на 400гб, узнаете что такое нулы которые вам не нужны вообще. Если вам нужен нулл то спорить нечего, но когда пишут
time int defaul 0
то подумайте зачем вам нул который тут не нужен и будет только мешаться.
И еще открою тебе тайну, раз не знаешь, индексы по строке индексируют только 1 символ, а представь когда будет 5млн записей по 1символу, вот тут научитесь пользоваться unsignet int not null и хеши по b-tree ...
и для выводов по запросу, как раз нужно вспоминать про эти 2 важных правила...
Привет, парни. Я анон, делавший борду в прошлых двух тредах, решил прикрутить к ней систему пользователей. Типа как у людей: админы, модераторы, абу, все дела.
Идея, я ёё нашел где-то на стэковерфлоу, следующая:
пользователь заходит в систему, его имя и, возможно, ещё какие-то данные пишутся в сессию. Если он при входе отметил пункт "запомнить меня", то дополнительно пишутся куки с именем и случайно сгенерированным при регистрации токеном. В следующий раз проверяется наличие кук. если имя и токен совпадают с указаными в таблице происходит авторизация.
ПХП-анон, можешь посмотреть мой код? Там все по-сути происходит с в трех файлах - Application/Model/User.php,
Application/Controller/User.php и Application/Core/ Auth.php
>>335425
Ах да, ссылку забыл:
https://github.com/melanchthon/board
>>335400
>дескриптор потока
Пожалуйста объясни в двух словах или дай ссылочку где почитать, что это? Погуглил и не много не понял, а может и не то нагуглил. Спасибо :3
Все-тот-же-анон
>>335437
Поток — в данном случае значит «открытый файл». Дескриптор значит «идентификатор».
Когда ты открываешь файл с помощью fopen, ты получаешь (если все ок) дескриптор потока — специальное значение типа resource, которое нужно сохранить в переменную:
$fd = fopen('php://stdin', 'r');
Этот дескриптор передается в функции работы с файлами, например, fread, fgets, fwrite, чтобы указать им, с каким потоком работать. без дескриптора нельзя, так как непонятно откуда именно ты хочешь читать данные. Ведь кроме стандартого ввода (то есть клавиатуры), данные можно читать из файла, из сетевого сокета, откуда угодно.
Для начала почитай мануал:
http://www.php.net/manual/ru/function.fopen.php
Кроме fopen() есть еще fclose(), которая закрывает файл, когда он тебе больше не нужен, но для чтения с клавиатуры он не нужен.
Ты можешь спросить, я же хочу вводить данные с клавиатуры, при чем тут файлы и файловые дескрипторы? Отвечаю, в linux такая концепция, что данные с клавиатуры можно читать теми же функциями, что и данные из файла или сетевого соединения.
Вот например, как можно прочитать строку из файла:
$fd = fopen('file.txt', 'r');
$line = fgets($fd);
Как видишь, код точно такой же, только первый параметр у fopen поменялся. Линуксу (и PHP который во многом взялего идеологию) без разницы откуда читать/писать данные, это делается одной и той же командой.
Кстати, в PHP этот функционал расширили еще дальше. С помощью stream wrappers ты можешь через fopen не только открыть файл, но и читать данные из TCP-, HTTP-соединения, gzip-архива и много чего еще.
>>335425
О, пользователи — это хорошо. Но тут немало подводных камней.
Начнем с сессий. У сессий в PHP есть подвохи:
- время жизни (кстати, хороший вопрос для заваливания новичков и даже опытных программистов на собеседовании). Знаешь ли ты, как и когда удаляются сессии? Вообще, это зависит от ОС и настроек php.ini. В дебиане, например, сессии удаляет крон, котрый запускается, по моему раз в 15 минут и удаляет все файлы сессий, в которые не велась запись в течение 24 минут. Это значит, что если ты откроешь форму добавления поста, потом полчасика позанимаешься чем-нибудь другим, потом все-такие напишешь пост, ты можешь оказаться разлогиненным.
- блокировка. По умолчанию, сессия блокируется при открытии, и если второй процесс пытается открыть ту же сессию, он ждет пока первый не закроет ее. Это может быть актуально там, где например активно используются AJAX-запросы — они будут блокировать друг друга:
http://habrahabr.ru/company/bitrix/blog/179803/
http://habrahabr.ru/post/62412/
http://habrahabr.ru/post/182352/
Конечно, можно похимичить с настройками PHP, но лучше, по моему, особо не полагаться на сессии. Например, в случае авторизации, можно выставлять куки в любом случае — только если не выбрано «запомнить меня» ставить сессионные куки (куки, у которых не вставлено время жизни и которые удаляются при закрытии окна браузера).
Теперь про куки. У кук есть полезный флаг — httpOnly. Куки, отмеченные этим флагом, недоступны яваскриптам на странице и их нельзя угнать с помощью уязвимости XSS. Думаю, стоит этот флаг использовать: http://www.php.net/manual/ru/function.setcookie.php
Теперь про удобство пользования твоей регистрацией. Оно, по моему, ниже нуля:
- при ошибке в форме логина/регистрации поля сбрасываются, надо вводить данные второй раз. Зачем?
- после регистрации, надо же, я могу войти на сайт с помощью формы логина, то есть по второму разу ввести логин и пароль. Внимание, вопрос: почему я должен это делать?
Посмотри, как сделана регистрация в фейсбуке, твитторе. Там ничего подобного нет, после регистрации ты сразу же оказывешься залогиненным.
- какие-то дурацкие требования к паролю. Минимум 8 символов, да еще и должны быть цифры. То есть giYhdi — плохой пароль, а 12345678 — хороший? Причем ведь об этом еще никто не предупреждает заранее, ввел gYuhdy — фиг тебе, вводи все заново.
- нельзя войти через фейсбук, твиттор, одной кнопкой, надо регистрироваться.
Также, хорошо бы как-то отличать посты зарегистрированных пользователей от анонимов. Можно, например, запретить анонимам вводить имя в форме постинга или же выделять цветом имена залогиненных юзеров. Ну и вообще, тем, кто прошел регистрацию, надо давать какие-то няшки и преимущества, иначе зачем это делать? Тем, кто входит через соцсети, надо давать няшки вдвойне, так как от таких пользователей мы получаем максимум ценных данных.
Теперь про безопасность. Плохо:
Токен пользователя один и никогда не меняется. Спер токен из кук, например, трояном, и заходи когда угодно из любой страны
Нет привязки кук к IP. Здесь есть как недостатки, так и положительные стороны. Привязка хороша тем, что стыренным токеном не воспользоваться с другого компьютера с другим IP. Недостатки:
- если юзер с айпадом выходит из дома (переключаясь с WiFi на 3G), он разлогинивается
- у мобильных операторов и операторов с динамическим IP адрес может меняться (но при этом он обычно из той же подсети, первые 2-3 числа в IP совпадают)
Потому, привязывать, или нет — сложный вопрос. Соцсети вроде вконтакте и платежные системы обычно при входе с другого IP начинают просить либо перезалогиниться, либо ввести последние цифры номера телефона.
Защита от подбора паролей
У тебя ее нет. Можно хоть в 100 потоков перебирать пароли. Обычно делают по другому: если с одного IP больше нескольких ошибок входа за последние N минут, показываем капчу.
>>335425
Теперь про CSRF.
У тебя можно легко принудительно разлогинить юзера: заманиваем на свою страницу (например, постим ссылку с подписью «смотрите какие няши! http:// t . co / 12345678»), а оттуда редиректим их на /user/logout .
А можно на этой же странице разместить невидимую форму постинга, которая заполнена и автоматически сабмитится при заходе на страницу, и юзер от своего имени публикует пост (вроде я ньюфаг на 30% проверь насколько ты ньюфаг). Причем в пост можно поместить ссылку, по которой будут переходить другие.
Это и называется уязвимость CSRF: http://intsystem.org/768/learn-about-csrf-intro/
Как защититься от CSRF? Просто: генерируем уникальный токен, зависящий например от IP адреса (ну или лучше, от адреса подсети). Добавляем его в формы невидимым полем и в ссылки вроде logout. И проверяем его наличие. Злоумышленник не может угадать значение токена и не может подставить его в свою форму.
Не стоит полагаться на проверку Referer: в стандарте написано, что браузер не обязан его отправлять, антивирусы, фаерволлы, расширения могут его вырезать или менять, он может быть отключен в браузере, и есть способы отправки запросов с обнулением referer.
Теперь по коду
> $hash = md5($salt.$pass);
О, это хорошо, что ты используешь соль. Потому что для md5 без соли существуют готовые радужные таблицы: https://www.freerainbowtables.com/en/tables2/ — обрати внимание, например таблица md5_mixalpha-numeric#1-9 расшифровывает пароли из букв и цифр до 9 символов при весе в терабайт. И с ростом мощностей компьютеров их будет расшифровать еще проще.
Обрати внимание, в PHP5.5 появились стандартные функции шифрования паролей: http://habrahabr.ru/post/194972/ — со временем стоит отказаться от велосипедов с md5 и переходить на них.
> ADD CONSTRAINT comment_ibfk_1
FOREIGN KEY (post_id
) REFERENCES post
(id
);
Зачем удалил из дампа?
> $user->name = $_POST["name"];
Лучше бы сделать через isset($_POST["name"]) ? $_POST["name"] : '' или через функцию, а то кто-нибудь будет слать пустые пост-запросы и забивать логи варнингами о несуществующем значении массива. То же самое и с $name = $_COOKIE['name']; — куки может и не быть.
> $STH->bindValue(":name",$user->name);
> $STH->bindValue(":pass",$user->pass);
Можно передавать массив в execute:
$STH->execute(array(
':name' => $user->name,
....
));
> userExists
Лучше назвать getUserIfExists(), названия функций надо начинать с глагола.
> checkPass($pass,$realHash,$salt)
Эту функцию, кстати, можно перенести и в класс Core_User, оставив только параметр $pass
> if (strlen($user->name)<5)
Надо использовать mb_strlen
> <span>Добро пожаловать, <?=$auth->getName()?>! </span>
htmlspecialchars бы не помешал.
У тебя в коде есть поиск пользователя по name, а индекса на первые N символов name нет, нехорошо, MySQL'у придется всю таблицу обходить чтобы найти пользователя. Нет проверки уникальности логина, можно зарегистрировать несколько пользователей с одинаковым или отличающимся только регистром букв логином. Нет ограничения и проверки на максимальную длину логина. Нет проверки на разрешенные в логине символы, хотя может это и хорошо. Нет защиты от регистрации под логином «администратор сайта» или «модератор».
У данных, ввденных в форму, надо делать trim() так как пользователь может нечаянно впечатать пробел в начале или конце и не заметить.
про палиндромы решил вот
http://ideone.com/QrVm4z
спасибо за задачки, Опушка
>>335507
Молодец, программа работает правильно. Едиснтвенное, вместо этого:
($lower == $reversed) ? $result = "Это палиндром" : $result = "Не палиндром";
Лучше нормально использовать if/else (ради читабельности). Тернарный оператор обычно используют как выражение, а не как отдельную команду. Ну или можно переписать это в виде:
$result = ($lower == $reversed) ? "Это палиндром" : "Не палиндром";
Так сразу видно, что это команда присваивающая переменной result какое-то значение.
Присоединяюсь к вашему клубу. Вот мое решение задачи про айфон в кредит
http://codepad.org/fxTTiwWS
>>335580
Мое решение задачи про банк в догонку http://ideone.com/rvMBeo
>>335580
Ну здравствуй. Айфон в кредит — все решено верно, хорошо, у анонов обычно эта задача проблемы вызывает. Задача про банк — считает верно, но не пишет сколько же лет анону будет в заветный день.
Проясните за die/exit, почему-то вижу их буквально в каждом коде во всех местах, хотя не понимаю что такого полезного в этих операторах, кроме сообщения про ошибки. Где надо использовать?
>>335597
В консольном скрипте, например, при ошибке. Или чтобы завершить выполнение скрипта, не доходя до конца. Если не видишь ничего полезного — можешь не использовать.
>>335682
Это же отлично:
- если на дохлосайт полдня никто не заходит, приложение не запущено и не ест память сервера. Это позволяет хостить тысячи малопосещаемых сайтов на одном сервере. А теперь попробуй-ка захостить 1000 ява- или питон-приложений.
- поскольку скрипт умирает, то не надо тратить время на отладку, например, утечек памяти (например, когда приложение добавляет данные в кеш без ограничений и в итоге падает). Это позволяет использовать более дешевых и менее квалифицированных специалистов.
>>335349
http://ideone.com/pNXsox как оно?
>>335690
Все верно, только вот strtr($word1,$st1); — это ты наверно забыл убрать, от этой команды ошибки идут из-за неопределенных переменных.
>>335693
ага.
>(число элементов - 1)
а зачем -1.
хард моде: переделай под стиль Маяковского
у этого ведь нет програмного решения?
>>335704
> а зачем -1.
Сделай массив из 5 элементов, например, сделай var_dump($array) и посмотри какие индексы у элементов. В массиве из 5 элементов нет элемента с индексом 5, они нумеруются с 0 до 4.
> у этого ведь нет програмного решения?
Нет, наверно. Надо поменять исходные слова на более подходящие (жесткие и решительные) и схему предложения, у Маяковского обычно стихи всякими столбиками и треугольниками идут.
Оп, я правильно понял суть первой задачи на регулярные выражения или тут надо было просто проверить строку на соответствие одному шаблону? (Я подумал, что шаблон, соответствующий требованиям задачи получился бы довольно громоздким. Или нет?).
http://ideone.com/ixAx6y
>>335761
Ну вообще не такой и громоздкий, если подумать. Это можно сделать одним preg_match. Но как у тебя, тоже работает.
Если ты хочешь удалить символы, то вместо preg_split + implode проще использовать preg_replace (или ее ты пока не изучил?) или strtr.
>>335764
Ох, спасибо, совсем забыл про strtr. Я сегодня прочитал, что вообще предпочтительно пользоваться строковыми функциями вместо регулярных выражений там, где это возможно, т.к. они быстрей.
Как лучше хранить много картинок, например, обложек книг для каталога?
1. Все в одной папке, с рандомными именами типа be677264d0_poster.png, be677264d0_thumb.png + отдельное поле в базе с именем.
2. Каждую в отдельной папке вида /books/.$title/ со стандартными именами типа poster.png, thumb.png. Поле в базе при этом не нужно, проверки существования и генерации имен тоже.
Второй вариант выглядит намного изящнее, но нет ли каких-то подводных камней с производительностью из-за множества папок?
>>335827
> нет ли каких-то подводных камней с производительностью из-за множества папок?
Подводные камни есть когда в каталоге много файлов и ты пытаешься его открыть каким-нибудь файловым менеджером — тормозит.
Так что возможно лучше сделать каталог двухуровневым, с использованием id в имени, напрмиер:
/books/162/162354.png
/books/102/102500.png
Если не надо лезть в базу, это плюс.
Есть переменная. В ней html текст.
В тексте абзацы, бр теги и картинки. Другое исключено (strip_tags же)
Мне надо сделать:
1. так, чтобы каждая картинка была выкачана в папку /images
2. Заменен путь этой картинки на локальный адрес
Я не прошу написать вместо меня, я прошу помочь и дать наводку на то, что именно гуглить и какие техгнологии надо использовать.
Пишу свой RSS ридер, обучаюсь.
>>335831
1) можно регулярками (preg_match_all, preg_replace) найти URL картинок и регулярками же заменить
2) можно загрузить HTML в DOM дерево (DomDocument::loadHtml) и в дереве искать все элементы IMG, после чего поменять им аттрибут src и преобразовать назад в HTML.
>>335833
И еще, надо чтобы текст был гарантированно в utf-8, кодировка на входе может быть ЛЮБАЯ. Как сделать?
Питоняши и рубисты ! В ваших языках есть простой способ рекурсивного обхода дерева, с использованием какой-нибудь стандартной функции? Например, есть дерево каких-нибудь объектов, надо его обойти и с каждым что-нибудь сделать. Или посчитать сумму чего-нибудь.
Просто интересно, проще это чем в PHP или сложнее.
>>335834
Определяешь кодировку на входе (по заголовку Content-Type, тегу meta charset и другим правилам описанным в стандарте HTML) и преобразуешь в utf-8 через iconv()
>>335833
а выкачать картинки как?
Т.е. мне надо гуглить регулярные и их учить, а по DOM что гуглить?
>>335842
В XML указана кодировка в первой строчке иначе это utf-8:
<?xml charset=.... ?> (или как-то так, погугли)
>>335838
любым из способов:
1) курл + самописный велосипед
2) file_get_contents('http://...')
3) Zend_Http
4) http://requests.ryanmccue.info/
5) Guzzle
> Т.е. мне надо гуглить регулярные и их учить, а по DOM что гуглить?
У меня есть урок по регуляркам: http://archive-ipq-co.narod.ru/l1/regexp.html
По DOM гугли «php работа с dom»
Я написал может не очень понятно, так что напиши если что-то не понял.
>>335842
Плюс, как я понимаю, если ты используешь DOM:
$dom = new DOMDocument('1.0', 'utf-8');
$dom->loadXml('....');
то он сам решает проблемы с кодировками. Мануал по DOM (большой): http://www.php.net/manual/ru/class.domdocument.php
Оп запости решение второй задачи на регэкспы. часов пять пытаюсь решить нихуя не получается, уже вырубаюсь. Приду завтра с работы гляну.
>>335845
Смотри, дружище.
xml имеет кодировку utf-8
Файл с php кодом тоже.
Беру из файла и пишу в бд. В бд - пикрелейтед.
utf8_encode() не помогает.
как решить эту проблему?
>>335910
Ну так может у тебя в БД через одно место кодировка выставлена? Ты запрос SET NANES utf8 при соединении с БД делаешь или надеешься на авось, что все само правильно выставится?
Также хочу спросить, что за криворукий инвалид сделал так, что при обновлении капчи вся страница блокируется??
>>335912
Делаю
> $link = mysql_connect('localhost',$user, $pass) or die ('пиздец нахуй!'.mysql_error());
>mysql_query('SET NAMES UTF-8');
ОП, помоги пожалуйста установить Apache+PHP+MySQL. Какие только дистрибутивы не попробовал, как только не делал, второй день уже не могу установить. Апач ставится, вбиваю в адр.строку локалхост, все хорошо. Все работает, включается, выключается. Устанавливаю PHP, тут и начинается весь геморрой. Ставится вроде все хорошо, но после перезапуска Апача он больше не включается. Пишет либо "Невозможно запустить, специфическая ошибка 1", либо выскакивает отчет об ошибке Майкрософта, что приложение завершило свою работу. Из конфига Апача убираю когда последние строки о подключении модуля php, то все норм становится, Апач запускается. Сколько искал, так не смог найти ответы. Подкинь пожалуйста проверенно рабочий софт, который не конфликтует между собой. Вроде все делаю по гайдам, но ничего не получается. Вот что попробовал последнее:
httpd-2.2.18-win32-x86-no_ssl-r2.msi
php-5.2.16-Win32-VC6-x86.msi
mysql-5.5.34-win32.msi
Шиндоус ХР, сервис пак 3.
До установки MySQL так и не добрался пока.
>>335464
Про привязку к IP в-целом понятно. Но вот как привязать к подсети непонятно нихуя.
Смотри, насколько я понимаю IP-адрес состоит из двух частей: адрес подсети/адрес узла, аналогия - название улицы/номер дома. Адрес подсети можно высчитать из IP зная маску подсети - она для каждой подсети своя, я всё правильно понял?
Ну и собственно вопрос, я могу узнать айпи из $_SERVER['REMOTE_ADDR']? но как мне узнать из него собственно адрес самой подсети, не зная маски? Ткни носом, пожалйста, не могу разобраться.
Спасибо большое ОП за уроки. Пару месяцов назад сделал почти все уроки кроме регулярок, но мне очень жаль, что нет уроков по mysql. Теперь начну с более практических уроков. Хочу написать сначала гостевою, а потом и форум...
>>335976
Нет, это что-то на уровне Денвера. Я сейчас смотрю специалиста, дошел до момента работы с базами данных, там идет работа из под командной строки. Денверский же MySQL настроен как-то по другому, или я пока не могу разобраться во всем этом из-за недостаточного уровня знаний. Уж лучше установить все как и у преподавателя, дабы не путаться и не ломать голову. Застопорился даже на моменте подключения к самой БД MySQL, решил установить все по отдельности, но уже два дня вместо занятий ломаю голову над установкой.
>>335933
Диапазоны IP адресов распределяет вроде бы IANA, она раздает большие блоки региональным реестрам, они выдают из них кусочки поменьше, и так далее. Наверно, эти реестры можно собрать, но это долго.
> она для каждой подсети своя, я всё правильно понял?
Верно. Маску можно конечно узнать через хуиз: http://whois7.ru/?q=8.8.8.8
NetRange: 8.8.8.0 - 8.8.8.255
CIDR: 8.8.8.0/24
Но во-первых, ты замучаешься это писать, во-вторых, whois-сервера забанят тебя за постоянные запросы. Тут надо иметь локальную базу, и искать по ней.
Ну или можно поступить проще: считать, подсетью первые 2 или 3 цифры IP адреса. Это будет неточно, но в большинстве случаев работать как нам надо.
>>335930
Версия Php совместима ли с апачем? Все ли пути и библиотеки прописаны, все ли в правильные папки разложено? Апач лучше брать с apachelounge.
Вот например: апач http://www.apachelounge.com/download/
Обрати внимание, Minimum system required: Windows 7 SP1, Windows 8 / 8.1, Windows Vista SP2, Windows Server 2008 R2 SP1, Windows Server 2012 / R2
XP не поддерживается, если у тебя XP бери чтонибудь постарее, например VC10 или VC9: http://www.apachelounge.com/download/win32/
Поскольку Апач собран с VC10, наверняка надо к нему с сайта майкрософт будет скачать Visual C redistributable 10 (ссылка на странице скачивания есть). Проверь, что версия x86/64 соответствует битности компа и ОС.
Потом идем качать PHP: http://windows.php.net/download/
Бери VC10 (лучше такой же как у апача!) или Vc9, thread safe (обязательно для апача под виндой), x64 или x86 в зависимости от битности компа.
Обрати внимание, Php 5.5 тоже требует минимум Windows 7. Раз у тебя XP, бери 5.4.
>>335930
Еще советы: если при запуске Апача с Php пишется «не найдена какая то библиотека попробуйте переустановить прилоежние» то это скорее всего у тебя какая-то папка важная не добалена в PATH. Добавь, не спеша перезагрузись и продолжай эксперименты.
Вот еще пасты, может помогут:
http://gist.github.com/anonymous/2dfa134fe20d9cf91bbe Как научиться пользоваться командной строкой
http://gist.github.com/anonymous/946f4f1830be3955fe17 Как установить Апач (старая)
>>335960
А что писать гостевую? У нас есть задачка «запрограммировать имиджборду», причем верстка уже готовая есть, смотри какая: https://github.com/codedokode/board-markup
Не хочешь попробовать?
Уровень: нужно знать PHP и SQL хотя бы немного
Цель: научиться писать приложения, а не простые скрипты, познакомиться с MVC, повысить практические навыки.
Данные хранятся в базе данных, например, MySQL. Схему БД (то есть список таблиц и полей) предлагаю придумать самостоятельно, считай это частью задания. Позже (если твой код заработает) мы будем тестировать твой код, насколько он хорошо справляется с нагрузкой, и возможно, менять схему БД, если будут проблемы.
Нужно использовать ООП.
>>335990
Да, версия совместима с Апачем. Библиотека для Апач2.2 имеется, PHP автоматически прописывает к ней путь, когда при установке указываю расположение httpd.conf. Я пробовал качать Апач с apachelounge, но так и не понял что они мне предлагают, так как вместо инсталятора скачались какие-то папки и пару файликов. Что с ними делать так и не понял.
Да, про поддержку старых и новых версий уже читал. На официальном сайте Апача говорят лучше качать Апач2.2, чтобы запустить его с VC6. Как же все запутано. Очень жаль, что на уроках в Специалисте не показали так сказать наглядную установку, а показали лишь на картиночках. А про не найденную библиотеку не писал, писал только про "Специфическую ошибку 1". Сколько гуглил - ответы были что мол был невнимателен, вместо одной папки в пути прописал другую, исправил и все заработало. 300 раз перепроверил, какие статьи только не попробовал, так и не получилось. Ладно, спасибо, ОП. Буду сносить ХР, поставлю семерку и буду пробовать на ней с более новыми сборками.
>>336002
> так как вместо инсталятора скачались какие-то папки и пару файликов. Что с ними делать так и не понял.
Это и есть сборка апача. Там есть файл readme, в нем описано как устанавливать. Берешь и ручками ставишь, а как ты хотел, это софт для настоящих бородатых программистов, а не блондинок с айпадом. Кряки к играм небось ставить умеешь, а апач не можешь. Вот что написано в ридми:
|Install
|-------
|- Unzip the Apache24 folder to c:/Apache24 (that is the ServerRoot in the config).
распакуй и скопируй содержимое папки Apache24 например в c:\Apache24 или куда-нибудь еше.
| Default folder for your your webpages is DocumentRoot "c:/Apache24/htdocs"
| When you unzip to an other location, change ServerRoot in the httpd.conf,
| and change in httpd.conf e.g. the Documenroot, Directories, ScriptAlias,
| also when you use the extra folder config files change to your location there.
Можно распаковать в другую папку, но тогда надо будет поменять указанные настрйки в httpd.conf
| Start apache in a DOS box:
Запуск Апача из командной строки
|httpd.exe
| Install as a service:
Установить в систему как службу
|httpd.exe -k install
| ApacheMonitor:
| Double click ApacheMonitor.exe, or put it in your Startup folder.
Можешь создать ярлык на ApacheMonitor на рабочем столе или в меню пуск для удобства.
| Буду сносить ХР, поставлю семерку и буду пробовать на ней с более новыми сборками.
только не думай, что это избавит от необходимости разбираться.
>>336004
Как все запутанно. С каждым днем чувствую себя все более и более криворукой макакой, тяжело усваиваю материал. А тут еще и с установкой софта такой фейл, не понимаю, как люди по книжкам это читают и делают.
Спасибо за перевод, так будет гораздо проще.
А про игры нет, в них я совсем не играю, разве что майнкрафт иногда. Большинство времени провожу тупо скроля интернеты, бессмысленно тратя время, поэтому собственно решил осваивать данный язык. Паскаль в быдловузике совсем не вдохновляет, но вроде как дал неплохую почву для какого-никакого понимания других языков.
Доброанон, посоветуй. Есть сайт. Сайт наполняется статьями. Мне сказали, причем весьма уверенно, что для поисковой оптимизации очень хорошо в адресной строке иметь написанное транслитом название каждой статьи. То есть вместо page.php?id=12345 нужно делать page.php?name="kak zavyazivat galstuk" и потом делать это красиво через mod_rewrite. Здесь id и name - соответственно номер и название статьи. Дак вот, правда ли это, что так делать лучше (все популярные сайты и правда так делают) и как это реализовывать? Вводить специально транслитную версию отдельным полем в БД или использовать русское имя, но какими-то функциями перегонять его в транслит для адресной строки? Еще вопрос, если в БД куча статей, запрос, содержащий where name='kak zavyazivat galstuk' ведь должен сильно тормозить? Это же поиск по тексту почти. Вообщем, как делать правильно, расскажи, посоветуй.
>>336006
Запутанно когда ставишь по советом двачей..прочитай хорошую книжецу про unix и все распутается у тебя
>>335540
Почему когда вводим другую фразу-не палиндром,все равно пишет что это палиндром,где-то косяк,помоги найти :3
>>336086
Что-то я проглядел это.
$reversed .= mb_substr($lower, $i, 1);
Ты прибавляешь буквы в конец строки. Попробуй добавлять в начало:
$reversed = mb_substr() . $reversed;
Или же переделай цикл, чтобы он шел не с первой до последней буквы. а с последней до первой.
>>336036
SEO обсуждается в разделе /web. Я могу прокомментировать с личной точки зрения и с т.з. технической реализации.
> page.php?id=12345
Я слышал, поисковики считают то, что идет после впроса дополнительным параметром, и воспринимают все это как одну страницу page.php. Хотя, с другой стороны, такие страницы и индексируются и ищутся. Смотрится отстойно.
Мое личное мнение, автосгенерированные адреса транслитом выглядят как кошмар: http://example.com/pitanie/zyri-i-vitaminy-dlya-zdoro-16312.html
Но если ты оптимизируешь под роботов, может им это и нравится.
Хорошо могут выглядеть заданные вручную URL: http://exanple.com/nutrition/vitamins. Пример — URL новостей на lenta.ru.
Что касается технической реализации, то конечно надо хранить URL в базе. Для поиска можно поставить индекс по полю, например на первые 8-16 символов.
>>336036
У меня есть еще паста про URL (с точки зрения человека, а не робота): https://gist.github.com/codedokode/772a4ccc03e41d6b7cba
Аноны, я знаю, среди вас есть те, кто немного изучил HTML/CSS и берется за яваскрипт. Вот вам ссылочки для вдохновения:
Учебник JS на русском: learn.javascript.ru
Серия постов на Хабре про маленькие программки на яваскрипт:
http://habrahabr.ru/post/202556/ Гоночка на JavaScript (30 строк кода)
http://habrahabr.ru/post/202530/ Крошечный арканоид на JavaScript (30 строк кода)
http://habrahabr.ru/post/202304/ Крошечный Excel на чистом JavaScript (30 строк кода)
habrahabr.ru/post/202476/ Крошечная змейка на JavaScript (30 строк кода)
habrahabr.ru/post/202628/ Tetris на javascript (в 30+ строк)
http://habrahabr.ru/post/202684/ Roguelike/RPG на JavaScript (30 строк кода)
Изучайте.
чего-то никак палиндром не получается,что я делаю не так
http://ideone.com/NGgItv
>>336152
$half2=strrev($half1);
Ты читал что там в учебнике написано про strrev? После задачи, там еще картинка есть с 2 чуваками на крыше.
Ебался-ебался я со второй задачей на регулярки, и вот только сейчас доделал: http://ideone.com/ZGLiNh
.
А всё потому, что никто блджад в этом сраном мануале не потрудился сообщить о том, что функция preg_match_all, если ей передать флаг PREG_OFFSET_CAPTURE будет выдавать смещение в БАЙТАХ а на в символах...
Я очень долго пытался вкурить почему же всё работает не так, как надо.
>>336242
вот прогнал через http://beta.phpformatter.com/ если что.
http://ideone.com/QpWj9l
ОП, это кун который вчера спрашивал тебя про не работающий Апач когда к нему подключаю php. По твоему совету скачал Apache 2.4.6 Win64 с http://www.apachelounge.com/download/. Ставил на Win8.1 64x. Все установилось, как служба поставился, из под командной строки все запускается. Но проблема опять та же самая. Как только привязываю к Апачу php - "Специфическая ошибка службы 1". PHP брал с http://windows.php.net/download/, попробовал версии PHP 5.5 VC11 x64 Thread Safe, и на всякий случай PHP 5.4 VC9 x86 Thread Safe (x64 не нашел). Visual C++ и Visual Studio 2012 устанавливал. Что только не делал. Даже Аллаху молился, все равно "Специфическая ошибка службы 1". PHP вроде подключаю правильно, не понимаю почему не работает. Помоги пожалуйста. По ссылке конфиг Апача (Подключение PHP в последних строчках):
http://pastebin.com/Ja3yCBkF
ОП, это кун который вчера спрашивал тебя про не работающий Апач когда к нему подключаю php. По твоему совету скачал Apache 2.4.6 Win64 с http://www.apachelounge.com/download/. Ставил на Win8.1 64x. Все установилось, как служба поставился, из под командной строки все запускается. Но проблема опять та же самая. Как только привязываю к Апачу php - "Специфическая ошибка службы 1". PHP брал с http://windows.php.net/download/, попробовал версии PHP 5.5 VC11 x64 Thread Safe, и на всякий случай PHP 5.4 VC9 x86 Thread Safe (x64 не нашел). Visual C++ и Visual Studio 2012 устанавливал. Что только не делал. Даже Аллаху молился, все равно "Специфическая ошибка службы 1". PHP вроде подключаю правильно, не понимаю почему не работает. Помоги пожалуйста. По ссылке конфиг Апача (Подключение PHP в последних строчках):
http://pastebin.com/Ja3yCBkF
>>336250
Сейчас разберемся. Сначала убедимся, что На apachelounge написано:
1) Be sure that you have installed Visual C++ Redistributable for Visual Studio 2012 : VC11 (vcredist_x64/86.exe) — установил библиотеку по ссылке (это не Visual Studio а Visual Studio Redistributable)?
2) Точно ли существует файл С:/PHP/php5apache2_4.dll который прописан в конфиге в конце? Проверить можно например командой
attrib С:\PHP\php5apache2_4.dll
Если файл не найден, то будет так и написано.
3) Проверь содержимое логов (в папке апача есть папка logs, а в ней скорее всего error.log и покажи нам)
>>336253
Трюки вроде установки на 64-битную систему 64-битного Апача и 32-битного PHP точно не сработают. Все должно быть одинаковой битности (включая библиотеку redistributable от майкрософт).
Привет, Анон.
Сперва скажу спасибо, благодаря тебе я устроился джуниором на пхп.
Но у меня проблема, которая заключается в следующем. Есть форма - вводишь данные, нажимаешь сохранить, и программа запихивает все в базу данных. Проблема в том, что после этого, если что-то поменять в инпутах и снова нажать Сохранить, то программа должна обновлять только что созданную запись. Как это лучше сделать?
Я думаю использовать такой вариант: после того, как данные в БД записаны, с помощью LAST_INSERT_ID получить id и сделать редирект на новую вьюшку, передав id. Потом уже извлекать данные, вставлять их в точно такую же форму, но при сабмите обновлять данные. Как думаешь, такое решение пойдет?
>>336246
> никто блджад в этом сраном мануале не потрудился сообщить о том, что функция preg_match_all, если ей передать флаг PREG_OFFSET_CAPTURE будет выдавать смещение в БАЙТАХ а на в символах...
Бывает. Ведь PHP-ники не сами писали обработку регулярок, а подключили библиотеку pcre, видимо на этот момент не обратили внимания.
Для преобразования байты → символы можно применить хак (мы отрезаем кусочек строки в байтах и считаем его длину в символах):
$offsetChars = mb_strlen(substr($string, 0, $offsetBytes));
Вообще, сделано неплохо. Выводится причина ошибки, это хорошо. Жаль, нелегко понять где именно, так как ошибочное место не выделено ни стрелочками, ни скобками, напрмер так:
...жывотное ...
↑
или так:
...→жы←вотное ...
...[жы]вотное ...
..._жы_вотное ...
>>336280
Да, сделай в форме скрытое поле id. Изначально оно пусто, а после создания записи делай редирект на адрес в котором есть id:
- открываем страницу scrip.php, форма пуста
- отправляем форму через POST, запись вставляется в базу и редиректит на scrip.php?id=12345
- при открытии этой ссылки в форму подставляется id из параметров и пишется текст «Редактирование записи 12345»
- когда ты отправляешь форму, скрипт по наличию id понимает что надо редактировать запись.
Обрати внимание на редикерт после POST. Это нужно чтобы при нажатии F5 не вставилась еще одна запись.
>>336288
>Обрати внимание на редикерт после POST. Это нужно чтобы при нажатии F5 не вставилась еще одна запись.
Можно насчет этого поподробней. И еще одно забыл. У меня же есть еще одна кнопка: сохранить и создать новое. Я так понимаю, различить какую кнопку нажал юзер можно только с помощью js, но вот как сабмитить форму при этом я совсем не въезжаю.
>>336290
Если у кнопки есть имя (name =), то вместе с данными формы отправляется параметр с именем нажатой кнопки (попробуй сделать var_dump($_POST) чтобы увидеть).
Но если ты хочешь извратиться делать через JS (например чтобы поддержать ИЕ6 который отправлял все кнопки button а не только нажатую), то тоже нет проблем. При клике на кнопку пишешь в скрытое поле что это за кнопка и делаешь form.submit(), где form — это DOM-нода формы (ее можно получить например getElemetnById()): http://learn.javascript.ru/forms-methods
>>336278
Ура! У меня все заработало, ОП, но я так и не понял в чем была ошибка. Нагуглил туториал вот этот:
http://www.youtube.com/playlist?list=PLV19T7yKWLmZkZl2Ti8fa3g4Sdyd3ZrBp
Поставил в точности такие же версии какие ставит и он, прописал все под диктовку и слава всем богам - завелось. Может я поставил не весь нужный софт, который требовался для новых версий (хотя и со старыми у меня ничего вчера не получалось), может еще что-нибудь. Но скорее всего из-за того что не настраивал файл php.ini, а лишь оставлял его как есть. Это может быть из-за этого? Даже не знал, что что-то нужно прописывать и там.
>>336303
Скорее всего ты опечатался когда прописывал путь к php в конфиге апача.
>>336304
Нет, ошибка точно была не в этом. Забыл дописать, что в пути перепроверял много раз и данная библиотека там точно присутствовала. Спасибо за разъяснения, на будущее буду уже знать про разрядность и прилагающий софт для корректной работы. Не думал что возникнет столько трудностей. Даже когда LAMP ставил на Убунту все было гораздо проще.
Похожие посты. Анон, как оно реализуется? Часто на сайтах при чтении статей есть раздел ПохожиеСтатьи. Какая статья похожа на какую - прописывается только вручную или есть какие-то механизмы, основанные на тегах, например? Зачем, кстати, нужны теги, куда их прописывать и что вообще с ними делать?
>>336366
Обычно берутся статьи с максимально близкими тегами. Или статьи из той же категории. Или же берется заголовок, удаляются стоп-слова и ищутся похожие. В общем, каждый придумывает свой велосипед.
> Зачем, кстати, нужны теги, куда их прописывать и что вообще с ними делать?
Если ты не знаешь, зачем они нужны, значит тебе они не нужны. Но вообще теги — это пришло из блогов, это что-то вроде тем, которые затрагивает пост, например:
«Работаем с Yandex Maps API», теги: JS, Yandex maps
«Никому нельзя верить», теги: отношения, печалька, когда это кончится
Потом можно найти все посты с тегом «JS» например. Посмотри например теги под статьями на хабре или в ЖЖ.
>>336155
http://ideone.com/cYEFd4
а теперь второй цикл отказывается работать
>>336427
http://ideone.com/kFbw80
быстрофикс,вроде работает
>>336306
Чому линукс в виртуалку не поставишь? Рабочий LAMP ставится одной командой, и все равно потом это будет работать на линуксе.
>>336397
тогда можешь рассказать, как они реализуются? В каком виде хранятся в базе, как происходит поиск по ним (допустим, количество статей, как на хабре или постов, как у жж, у каждого по 3-10 тегов). До черта же информации, поиск должен быть долгим
>>336445
Реализуются самым простым образом: таблица tags, где хранятся теги и таблица связи многие-ко-многим tags_to_posts. Для оптимизации (чтобы не джойниться при выводе постов) можно в таблицу постов в отдельном поле засунуть список тегов через запятую, но надо не забывать его обновлять при редактировании.
Поиск идет с помощью SQL-запроса SELECT наверно.
> До черта же информации, поиск должен быть долгим
Используй индексы и правильные запросы. Базы данных специально сделаны чтобы работать с большими объемами информации. Тем более что информации в тегах куда как меньше чем в статье или комментариях.
Зачем, кстати, ты пишешь свой велосипед, а не берешь вордпресс где уже все написано, есть теги и куча плагинов?
>>335764
>Ну вообще не такой и громоздкий, если подумать.
Я подумал и таки получилось. И правда несложно:
"/^[8\\+7]{1,2}[\\s(-]\\d{3}[\\s)(-](\\d[-)(\\s]?){7}$/"
Это третья задачка на регулярки.
http://ideone.com/ZGLiNh
>>336509
блджад не та ссылка http://ideone.com/eHNoCl
>>336509
Пропускает неверный номер: http://ideone.com/CXEkrb
Не пропускает верный: http://ideone.com/oIy5X6
Думаю лучше не задавать жестко 3 цифры в коде города, а разрешить любые 10 цифр + разделители.
>>336513
ох ты ж какой молодец, все дыры увидишь, спасибо.
>>336513
Пофиксил! Ну теперь-то не придраться, ОПушка.
http://ideone.com/jZZcAZ
>>336480
Можешь подробнее рассказать и, если не лень, пояснить примером? Как завести такое классное поле в базе данных, чтобы без связей и прочих жутких операций решить проблему? Тэгов много, у каждого поста их может быть с десяток, они часто в разном порядке стоят (или сортировать надо), постов может быть 10 000 и больше. Поиск по ним будет делом не очень быстрым, наверное.
>>336551
> Как завести такое классное поле в базе данных, чтобы без связей и прочих жутких операций решить проблему?
Ничего жуткого в связях нет.
Я-то могу рассказать, но у меня подозрение, что ты не знаешь ни понятия «многие ко многим», ни как работают индексы. В этом случае, тебе лучше почитать и изучить теорию сначала.
Для начала, почитай «Руководство по проектированию реляционных баз данных»: http://habrahabr.ru/post/193380/ желательно целиком.
Там описаны как раз способы связи таблиц, в том числе «многие ко многим».
Чтобы разобраться с тем, как сделать быстрым поиск по жалкому миллиону тегов, почитай:
http://xpoint.ru/know-how/MySQL/Optimizatsiya/Indeksyi
http://habrahabr.ru/post/31129/
http://habrahabr.ru/post/70640/
Если в этих статьях что-то непонятно написано, пиши, разберемся.
Сап, Антуаны, заебался искать примеры того, как на ПХП сжимать пачку файлов в файл.tar.bz2
Если не сложно, можно пример чтоб легко понять, что к чему. Файлы будут выбираться из папки по шаблону, я без понятия, как оно работает на ПХП с модулями сжатия, можно ли туда пихнуть массив имён файлов или надо по одному циклом добавлять. И нужно сделать так, что если всё прошло успешно, файлы потереть с папки. Всё что находил было про Phar и ни разу ни одного примера про tar.bz2, я не совсем знаком с вызовом команд из библиотек с "классами"(или как их там).
>>336606
Тут есть примеры кода: http://www.binarytides.com/how-to-create-tar-archives-in-php/ с Phar. Пример простой.
> я не совсем знаком с вызовом команд из библиотек с "классами"(или как их там).
Ну так изучи ООП. У меня есть первый урок по ООП тут: http://archive-ipq-co.narod.ru/l1/pasta.html
$query = 'SELECT topic_text_hash
FROM spc_topic
WHERE 1';
$result = mysql_query($query) or die ('циклу хэша облом!'.mysql_error());
$result = mysql_fetch_array($result,MYSQL_NUM);
echo $result[0].'<br/>';
echo $result[1].'<br/>';
echo $result[2].'<br/>';
//Почему в каждом элементе массива первый хэш из БД?
http://pastebin.com/VSrUJJqL
Тот же запрос в phpmyadmin работает и выдает все верно (пикрелейтед)
>>336823
Почитай мануал.
http://us3.php.net/manual/ru/function.mysql-fetch-array.php
fetch_array возвращает 1 ряд за раз, а не весь результат.
>>336841
Использовать цикл while: посмотри на примеры кода в мануале http://php.net/manual/ru/function.mysql-fetch-array.php
>>335260
ОП, ты, безусловно, няша, но откуда столько фанатизма по отношению к подавлению ошибок? Это не register_globals, которые плохо, потому что это пиздец. Если кодер понимает, что и зачем делает, то эта возможность полезна и не является признаком говнокода.
Вот, к примеру, Slim PHP, о котором ты хорошо отзывался. Не думаю, что его говнокодер писал.
В ту же степь - анализ html xml парсерами, которые вполне справляются с разбором, но выкидывают варнинги на невалидный html.
>>336965
@ тормозит же.
http://ideone.com/zhuX30 — без @
http://ideone.com/BmyVLu — c @
>>336965
> откуда столько фанатизма по отношению к подавлению ошибок
Потому что эта штука обычно используется юными быдлокодерами как костыль, чтобы кривой код побыстрее заработал.
> Вот, к примеру, Slim PHP, о котором ты хорошо отзывался. Не думаю, что его говнокодер писал.
Мне не нравится то, что у них написано. Я бы по другому сделал, пусть на несколько строчек больше, но зато никакие сообщения об ошибках не теряются. Там @ нафиг не нужен.
Напрмиер, вот это: @fopen('stderr', 'w') — какая ошибка может возникнуть при попытке открыть поток ошибок? Он обычно уже открыт и ошибок быть не должно, а если они есть то значит все совсем плохо и скрывать сообщения о них точно не нужно, наоборот, нужно их зафиксировать.
> Если кодер понимает, что и зачем делает, то эта возможность полезна и не является признаком говнокода.
Да ни фига. У каждого кодера свои представления о красивом коде. Если их не ограничивать жесткими рамками стандартов, то проект будет содержать все существующие стили именования функций, расстановки скобок, виды костылей и функции вроде mysql_query. Ну и до кучи найдется эстет, который будет лепить хакерские выражения вроде $sum += ++$sum << 1;
> В ту же степь - анализ html xml парсерами, которые вполне справляются с разбором, но выкидывают варнинги на невалидный html.
HTML надо парсить HTML-парсером а не XML. Ну тут ты прав, в PHP функция DOMDocument::loadHtml сделана кривовато:
> While malformed HTML should load successfully, this function may generate E_WARNING errors when it encounters bad markup. libxml's error handling functions may be used to handle these errors.
Заметь, что там есть ссылка, можно переключить эту функцию, чтобы ошибки не генерировались, а складывались в отдельный буфер, откуда их можно взять. Вроде в PHP есть еще пара функций, которые генерируют неотключаемые варнинги даже когда не нужно, но опять же, прежде чем ставить @ стоит посмотреть — может, эту проблему уже поправили?
Ололо я теперь гуру регулярных выражений, благодаря Опу.
http://ideone.com/is6Evl
http://ideone.com/bC4xUI
http://ideone.com/kMENMk
>>336999
О, неплохо. Но и тут есть баги.
Первая задача: http://ideone.com/1wFk6A — большие буквы заменяются на маленькие, и вместо $2 написано S2.
Вторая задача: все хорошо сделано.
Третья: все верно, работает.
>>337004
ОП-先生! я тебе еще покушать принёс! Отличная задачка, заставила подумать.
http://ideone.com/SZAvQY
>>337042
Боюсь, надо подумать еще. http://ideone.com/u8dvOx — этот текст что-то толком не обрабатывается, пробелы не исправляются.
Пагни,а если я выберу вебкодинг, полученный опыт поможет если я захочу кардинально поменять направление - геймдев, например при условии, что недостающие знания разберу?
ОПушка, помоги пожалуйста. У меня ТРУБЫ ГОРЯТ написать электронный дневник, который в последствии будет моей курсовой, а при полнейшей доработке дипломной работой. PHP изучая смотря Специалиста и попутно пописывая этот самый электронный дневник. Худо-бедно понял озы, дошел до MySQL, но чтобы в данном курсе понять как делать сложные запросы, нужно посмотреть весь второй курс, а на это времени совсем нет. Хочется пока просто понять как сделать нужную на данный момент мне вещь и писать нужные мне функции уже на php, которая будет выполнять требуемые запросы. Так вот, суть вопроса собственно пикрелейтед. У меня есть таблица users и months. В поле users поле id - ключевое, автоинткрементарное. В таблице months поле id тоже ключевое, автоинкрементальное. Суть в том, что мне нужно получить третью таблицу, которая также изображена на пикрелейтед и названа таблица info. Как мне сделать такую таблицу? Как мне в данной таблице поле id.Users сделать ссылкой на id в таблице users? Как поле id.Months сделать ссылкой на поле id в таблице users? Пожалуйста, объясни кратко как это реализовывается, а то повсюду написанно заумными словами и терминологией языка. Я же пока хуй простой, просто хочется поскорее начать доделывать, попутно также смотря Специалиста и постигать новые вершины. Можно ли ее как-то реализовать, чтобы я мог спокойно написать:
USE database;
SELECT * FROM info WHERE (id.Users = 5, id.Months = 11);
В итоге мне выводится таблица примерно такого вида:
id.Users id.Moths vsego_propuskov propuskov_po_neuv_pr
5 11 15 6
И при все этом в поле id.Users и id.Moths будут значения взятые из таблицы users и months?
Если не трудно - напиши пожалуйста подабающий запрос, на создание таблицы info. С меня твердое обещание разобраться как это делается и в будущем самому делать подобные вещи как раз плюнуть.
>>337092
Гугли JOIN, он объединяет таблицы вместе. Алсо поля надо называть нормально, например user_id или id_user, а не через точку. И конечно хорошо бы не транслитом.
>>337092
Вторая ссылка: http://www.mysql.ru/docs/man/JOIN.html
>>337072
Поможет, тем более что половина геймдева сейчас онлайн-игры делает.
Анон, ты советовал мне
>>333180
в ответ на этот пост вот эту либу
>>333191
До сих пор разбираюсь. Всё хорошо, все круто, но есть три больших подводных камня, точнее, два маленьких и один огромный.
1) Все круто, интерфейс хорош, но все это жутко избыточно, мне это все не надо, автоматы это очень здорово, гораздо круче регулярок, но мне нужно всего 5-10 тэгов, а для отключения всего остального надо сильно править исходники.
2) Хреново создаются стили css, все кидается в один класс и разбивается по типам, лучше бы делал отдельные классы с префиксами, а лучше, если бы я сам решал, где класс нужен, а где нет. Но это опять активно править исходники.
3) Третий и главный камень - для решения первых двух первых проблем мне не только не хватит опыта, но мне это делать не позволит лицензия, так как измененный код я опубликовать не могу, проект закрытый. Поэтому вопрос: есть ли что-то подобное, тоже на автоматах, но под MIT, например? Или решающее первые две проблемы. Сам написание вряд ли осилю.
>>337096
Окей, бегло окинув статьи понял что JOIN при при использовании селекта образует какую-то третью таблицу, где хранятся данные в которых объединены заданные поля. Я правильно понимаю? Но ведь мне не совсем это нужно. Мне нужно чтобы ввел я в форму допустим логин нового студента, его пароль, выбрал нужный мне месяц, ввел значения прогулов, отправил запрос. В итоге у меня данные в таблицк users добавляется новая строка, где id прописался автоматически, логин записался с отправленных данных, также пароль. В этот же момент, когда внесены в таблицу users необходимые данные, мы в таблицу info колонку users.id добавляем нового студента считанное с таблицы users, в колонке mouths добавляем значение переданное с формы, в колонки пропусков по ув и н/у причине добавляем также значение переданное с формы. Вот и все, добавили в таблицу users нового пользователя, расширили таблицу users и info, прибавив ей нужные значения.
Или я не так что-то понимаю?
>>337102
id.Users и id.Months - внешние ключи, но это только позволит контролировать целостность таблиц. Можно обойтись без них.
Добавлять строку в info придется отдельным запросом.
>>337106
>id.Users и id.Months - внешние ключи
То есть внешние - значит никак не относящиеся к таблице info? Значит в таблице info нельзя использовать какую-то ссылку на значение определенной строки из другой таблицы? Как же все запутанно.
>но это только позволит контролировать целостность таблиц
Вот это не совсем понял, пока не особо понимаю что подразумевается под целостностью таблиц.
>Добавлять строку в info придется отдельным запросом.
То есть у меня есть форма, куда я ввел информацию о студенте. Ввел его логин, пароль, месяца в который хочу вписать пропуски, все это записалось в какие-то переменные, переменные хранятся в сессии. Далее выполняется первый запрос, а именно запрос на занесение данных в таблицу users. Берем из сессии логин, пароль, добавляем их в таблицу. В итоге у меня в users появился новый пользователь. Далее пошел второй запрос. Второй запрос выбирает id этого последнего пользователя, запоминает в переменную. Пошел третий запрос. В третьем запросе идет вставка уже наконец-то в таблицу info, где поле id вставляется из переменной последнего созданного пользователя, поле id.mouths вставляется тоже из переменной в сессии, поле пропусков тоже из сессии. В итоге чисто теоретически получилась новая запись в таблице info, содержащая параметры которые мне были нужны. А уже селектом я могу использовать этот самый JOIN, объеденяя их и выводя нужную информацию. Это так должно работать? Это и есть связи, или это велосипед говнокодовый? И сам запутался, и вас наверное запутал.
аноны, такой вопрос: на локальном сервере установлен apache+mysql+php, создаю папку тестовую папку с данными сайта, помещаю туда index.php, все работает нормально. создаю вторую папку с сайтом, помещаю туда тот же файл-пишет нет прав доступа (в настройках апача и хостов все прописано верно), перемещаю данные второго сайта в папку первого - все работает, значит, если настройки одинаковы для обоих сайтов одинаковы, то дело в настройках апача, может кто-нибудь знает какие конкретно настройки отвечают за количество серверных имен, запускаемых с одной машины?
>>337114
Так. Смотри сюда.
- таблица info сама не создастся. Ты конечно должен создать ее руками (как и первые 2 таблицы).
- после этого, ты можешь использовать JOIN. JOIN объединяет в одном запросе несколько таблиц, примеры есть по ссылкам.
Насчет внешних ключей. Ты можешь (но не обязан)(но лучше это сделать) сказать MySQL что одна таблица ссылается на другую через ALTER TABLE (имена полей и таблиц подставь свои):
ALTER TABLE info ADD FOREIGN KEY id_user REFERENCES users(id) ON DELETE CASCADE ON UPDATE CASCADE
Это дает такие плюсы:
+ MySQL будет сама удалять связанные записи при удалении родительской
+ MySQL будет следить за целостностью связи и не позволит например случайно поменять id у связанных записей
+ программы типа adminer будут отображать связанные поля ссылочкой, по которой можно перейти на связанную запись
+ Это правильный классический подход
Теория на русском понятными словами: http://denis-in-ua.livejournal.com/7672.html
В общем, сплошные плюсы. Кстати, в старых учебниках пишут что FOREIGN KEY ничего не делает. Сейчас это не так, все работает. Так что научись использовать эту хрень.
> Вот это не совсем понял, пока не особо понимаю что подразумевается под целостностью таблиц.
Целостность — это когда какая-то запись A ссылается на запись B и та существует. Нарушение целостности - когда запись ссылается на несущестующую (например, запись B удалена или у нее криворукий админ поменял id, а ссылку в A не поменял). Если использовать FOREIGN KEY, MySQL будет следить за целостностью и блокировать недопустимые операции. Если не использовать — база в любой момент может превратиться в кашу одним неловким запросом.
> То есть внешние - значит никак не относящиеся к таблице info?
Внешний ключ — значит это поле содержит в себе id записи из внешней таблицы и таким образом ссылается на нее. Например, поле user_id таблицы info является внеш. кл. и ссылается на поле id таблицы user. Согласен, название дурацкое.
>>337114
> Далее пошел второй запрос. Второй запрос выбирает id этого последнего пользователя, запоминает в переменную.
Погугли насчет функции lastInsertId (например http://php.net/manual/ru/pdo.lastinsertid.php если ты как правильный пацан юзаешь PDO для работы с базой) — чтобы получить id последней вставленной записи есть готовое решение и надо использовать эту функцию, а не лепить велосипеды.
> Это так должно работать? Это и есть связи, или это велосипед говнокодовый?
Если не считать lastinsertId то все верно. Насчет JOIN, ты пока можешь руками вставить записи в базу и потренироваться писать джойны. Но вообще, джойн по сути просто объединяет 2 таблицы декартово (то есть для каждой строки первой таблицы подставляет все строки второй) и потом отсеиивает записи по условиям указанным в ON и WHERE.
>>337099
Ну не знаю, есть такие варианты:
1) освой регулярки по моим урокам например и заменяй BBCode на нужный HTML сам. Риск: накосячить и оставить дыр
2) Попробуй парсеры из гугла: https://www.google.ru/search?client=opera&rls=en-GB&q=bbcode+for+php&sourceid=opera&ie=utf-8&oe=utf-8&channel=suggest
Риск: неизвестно, насколько они кривы и дырявы.
3) Все же разберись с той библиотекой и научись ее правильно настраивать. Наверняка там все отключается через конфиг.
>>337102
> JOIN при при использовании селекта образует какую-то третью таблицу
Это воображаемая временная таблица, объединяющая сджойненные, которая создается на время SELECT и из которой выбираются данные. Никаких новых постоянных таблиц не создается.
>>337120
По идее каждый сайт описывается отдельно в конфиге апача. Пример: http://easylinux.ru/node/291/
Учти, сейчас в дебиане принято не сваливать настройки сайтов в один файл, а создавать на каждый конфиг в /etc/apache2/sites-available и включать из через a2ensite
Может. у тебя вторая папка в конфиге не вписана. ну и вообще, чтобы разобраться, то надо как минимум запостить конфиги и показать что пишется в лог ошибок.
>>337128
регулярки давно освоил, но это убого и есть куча случаев вроде вложенных или неправильных тегов, их регулярки не возьмут.
Хочу автоматы, как в библиотеке. Пару тредов назад ты пилил здесь мануалы про рекурсивные парсеры, это оно и есть? Я совсем не шарю в этих парсерах, автоматах... есть хорошие статьи по теории? Еще про парсер xml и сборку xml в PHP почти ничего не знаю, как-то было в книжке непонятно написано, я и плюнул. Видимо, зря. Базовые вещи типа того, что такое рекурсия и как ей считать факториал знаю, лол.
>>337137
Еще про парсер xml и сборку xml в PHP почти ничего не знаю, как-то было в книжке непонятно написано, я и плюнул. Видимо, зря.
>>337123
Это ведь то что нужно! Просто замечательно! Огромное спасибо, во многом разобрался и усвоил. Как это должно работать и с помощью чего понял, на сегодня можно со спокойной душой идти спать. Надеюсь завтра все получится реализовать. Если смогу реализовать эти базы с внешними ключами и делать правильные, корректно селекты из них - сам себя зауважаю.
>>337139
Я думаю, сможешь. Конечно, поначалу будут всякие странные ошибки выпадать, там опечататься легко, но разберешься со временем.
>>337137
Ну наверно, да. Я там правда больше про разбор математических выражений, но и про BB код что-то было. Но принципы общие:
1) разбиваем текст на токены (в твоем случае, наверно токены — это теги и текст между)
2) строим дерево из узлов и кусков текста, например методом рекурсивного спуска
3) строим по этому дереву HTML, обходя его рекурсивно (по правилам вроде тег [ b ] превращается в HTML-тег <strong>). На этом этапе важно использовать всюду htmlspecialchars, чтобы из исходного текста не пролез зловредный код.
Копипаста старого поста:
Это вообще-то стандартный способ разобра HTML, математических выражений, кода программ, с помощью токенайзера и парсера. Токенайзер с помощью регулярки или любым другим способом разбивает текст на теги и просто текст:
"Hello", "[ b ]", "[ i ]", "brave new", "[ / i ] ", "world!", "[ / b ]"
дальше парсер берет эти куски и хитрым методом, например, рекурсивным спуском, или как-то иначе, строит дерево, в котором элементы вложены друг в друга (что-то вроде дерева Dom в HTML):
Text "Hello"
Bold
Italic
Text "brave new"
Text "world!"
>>337138
Да ничего там сложного. есть расширение DOM. Создаешь пустой документ:
$doc = new DOMDocument(); (мануал: http://www.php.net/manual/ru/class.domdocument.php )
Потом содаешь элемент: $node = $doc->createElement('book'); // мануал гугли по слову «php DomElement»
задаешь ему аттрибуты:
$node->setAttribute('title', 'Повесть о рыбаке и рыбке');
добавляешь в документ
$doc->appendChild($node);
Сохраняешь документ в XML и выводишь:
$doc->formatOutput = true;
echo $doc->saveXml();
Ну естественно предполагается, что ты понимаешь что такое XML и понимаешь объекты. Ну если нет, то у меня есть первый урок по ООП, а про XML можно нагуглить наверно что-то.
Кроме DOM, есть еще XMLWriter — эта штука не строит документ в памяти, а сразу генерирует теги, она используется для работы с огромными документами, которые не влезут в память. Ну это явно не твой случай.
>>337059
http://ideone.com/WRHpta PCRE is my bitch.
>>337134
В конфиге апача вот это:
<VirtualHost *:80>
ServerAdmin [email protected]
DocumentRoot "D:/test1/www"
ServerName test1.loc
ErrorLog "D:/test1/logs/error.log"
CustomLog "D:/test1/logs/access.log" common
</VirtualHost>
<VirtualHost *:80>
ServerAdmin [email protected]
DocumentRoot "D:/test2/www"
ServerName test1.loc
ErrorLog "D:/test2/logs/error.log"
CustomLog "D:/test2/logs/access.log" common
</VirtualHost>
В логе ошибок:
[Sat Nov 23 01:27:17 2013] [error] [client 127.0.0.1] client denied by server configuration: D:/test2/www/
В логе доступа:
127.0.0.1 - - [23/Nov/2013:01:27:17 +0400] "GET / HTTP/1.1" 403 202
При запросе через браузер имени test1 прописал перенаправление на себя в файле хостов (Windows\System32\drivers\etc\hosts)прописал следующее:
127.0.0.1 test1.loc
127.0.0.1 test2.loc
Ошибки возникают только при запуске test2, с test1 все в порядке.
http://ideone.com/VGOSQ8
Оп, а почему когда я попытался написать вместо array_reverse shuffle, выдало не совсем то чего ожидал...
>>337180
Все, разобрался; в файле httpd.conf не прописал доступ к папке test2, соответственно при запросе адреса test2 в соответствии с файлом httpd-vhosts.conf апач пытался подключиться к папке D:/test2/www, но так как в httpd.conf не было прописано доступа к данной папке он выдавал соответствующую ошибку (client denied by server configuration: D:/test2/www/)... Как я понимаю, прописать путь в httpd-vhosts.conf еще не означает разрешить апачу работать с этой папкой, а просто указывает место поиска, а права доступа прописываются в файле настроек httpd.conf.
Пыханы пришла вот такая параша в задании на собеседование
0JfQsNC00LDQvdC40LU6DQrQodC+0LfQtNCw0YLRjCDRhNC+0YDQvNGDINGA0LXQs9C40YHRgtGA0LDRhtC40Lgg0L3QvtCy0L7Qs9C+INC/0L7Qu9GM0LfQvtCy0LDRgtC10LvRjzoNCjEu0JjQvNGPDQoyLtCb0L7Qs9C40L0NCjMuRW1haWwNCjQu0J/QsNGA0L7Qu9GMDQrQodC+0LfQtNCw0YLRjCDQv9GA0L7RgdGC0YPRjiDRhNC+0YDQvNGDINCw0LLRgtC+0YDQuNC30LDRhtC40Lgg0L/QvtC70YzQt9C+0LLQsNGC0LXQu9GPOg0KMS7Qm9C+0LPQuNC9INC40LvQuCBlbWFpbCAo0LIg0LrQsNGH0LXRgdGC0LLQtSDQuNC00LXQvdGC0LjRhNC40LrQsNGC0L7RgNCwINC/0L7Qu9GM0LfQvtCy0LDRgtC10LvRjykNCjIu0J/QsNGA0L7Qu9GMDQozLtCi0LXRgdGCINCi0YzRjtGA0LjQvdCz0LANCtCe0LHQtdGB0L/QtdGH0LjRgtGMINGA0LDQsdC+0YLRgyDRgdC70LXQtNGD0Y7RidC40YUg0YHRhtC10L3QsNGA0LjQtdCyOg0KMS7QoNC10LPQuNGB0YLRgNCw0YbQuNGPINC90L7QstC+0LPQviDQv9C+0LvRjNC30L7QstCw0YLQtdC70Y8g0YEg0L/RgNC+0LLQtdGA0LrQvtC5INC4INC/0L7QtNGC0LLQtdGA0LbQtNC10L3QuNC10LwgZW1haWwt0LDQtNGA0LXRgdCwDQoyLtCQ0LLRgtC+0YDQuNC30LDRhtC40Y8NCjMu0JLRi9GF0L7QtCAo0LfQsNCy0LXRgNGI0LXQvdC40LUg0YHQtdGB0YHQuNC4KQ0K0KLRgNC10LHQvtCy0LDQvdC40Y86DQoxLtCj0YfQtdGC0L3Ri9C1INC30LDQv9C40YHQuCDQv9C+0LvRjNC30L7QstCw0YLQtdC70LXQuSDQtNC+0LvQttC90Ysg0YXRgNCw0L3QuNGC0YzRgdGPINCyINCx0LDQt9C1INC00LDQvdC90YvRhQ0KMi7QodC10YHRgdC40Lgg0LDQstGC0L7RgNC40LfQsNGG0LjQuCDQtNC+0LvQttC90Ysg0YXRgNCw0L3QuNGC0YzRgdGPINCyINCx0LDQt9C1INC00LDQvdC90YvRhQ0KMy7QntCx0LXRgdC/0LXRh9C40YLRjCDQv9GA0L7QstC10YDQutGDINGD0L3QuNC60LDQu9GM0L3QvtGB0YLQuCBlbWFpbC3QsNC00YDQtdGB0LAg0L/RgNC4INGA0LXQs9C40YHRgtGA0LDRhtC40Lgg0L3QvtCy0L7Qs9C+INC/0L7Qu9GM0LfQvtCy0LDRgtC10LvRjyDQsdC10Lcg0L/QtdGA0LXQt9Cw0LPRgNGD0LfQutC4INGB0YLRgNCw0L3QuNGG0YsNCtCY0YHQv9C+0LvRjNC30L7QstCw0L3QuNC1IFplbmQgRnJhbWV3b3JrLCBDb2RlIElnbml0ZXIg0LjQu9C4INC/0YDQvtGH0LjRhSBwaHAvanMg0LHQuNCx0LvQuNC+0YLQtdC6INC00LvRjyDRgNC10LDQu9C40LfQsNGG0LjQuCDQt9Cw0LTQsNGH0Lgg0L/RgNC40LLQtdGC0YHRgtCy0YPQtdGC0YHRjy4NCtCg0LXQt9GD0LvRjNGC0LDRgjoNCtCg0LXQt9GD0LvRjNGC0LDRgiDQvdC10L7QsdGF0L7QtNC40LzQviDQv9GA0LXQtNC+0YHRgtCw0LLQuNGC0Ywg0LIg0LLQuNC00LUg0YTQsNC50LvQsCDQstC40YDRgtGD0LDQu9GM0L3QvtC5INC80LDRiNC40L3RiyBWaXJ0dWFsQm94INC40LvQuCBWTVdhcmUg0YEg0YDQsNC30LLQtdGA0L3Rg9GC0L7QuSDRgdC40YHRgtC10LzQvtC5INGB0LXRgNCy0LXRgNC+0LIgKHdlYiwgZGIpLCDRgtGA0LXQsdGD0LXQvNGL0YUg0LTQu9GPINGE0YPQvdC60YbQuNC+0L3QuNGA0L7QstCw0L3QuNGPINCy0YvQv9C+0LvQvdC10L3QvdC+0LPQviDQt9Cw0LTQsNC90LjRjy4NCg0K0JrQvtC90YLQsNC60YLRiyDQtNC70Y8g0YHQstGP0LfQuDoNCuKAotC80L7QsS46ICs3LTkxMy0wNzUtMDY2Ng0K4oCiRW1haWw6IHRpbW9raGluQHNpbmVyZ28ucnU=
Чего делать с этим говном или это заебанная кодировка? Я спрашивал про технические проблемы но тня пм ответила что все должно отображаться норм и я подумал что это говно часть задания. В файле не было никаких инструкций только надпись задание и выложенная выше абракадабра
Претендую на начинающую веб-макаку но с этим не сталкивался, что это вообще?
>>337200
джун конечно
еще дали написать бинарный поиск с изъебом и сумму подмассива но там легко
>>337197
Это список тестовых заданий тебе, дан он в кодировке base64.
Декодится здесь: http://base64.ru/
А вообще они охуели. Небось мухосранск с небольшим количеством фирм и большим числом никому ненужных быдлокодеров.
>>337202
спасибо бро
да не, я им сказал что студентота и что у нас учат хую корявому
Сказали что рук не хватает вообще
>>337205
>Сказали что рук не хватает вообще
Пиздят. Такие задания и в такой форме дают только те кому новые работники нахуй не нужны. Я бы даже не стал делать это всё, сразу бы нахуй их послал. Честно говоря, само такое задание выглядит как посыл на хуй, и не факт что после того как ты его сделаешь они тебя возьмут. Это больше похоже на прикол. Они бы еще AES'ом зашифровали 128-битным ключом.
>>337197
Короче, это пхп скрипт, чтобы привести его в нормальный вид, тебе нужно его деобфускировать. Вот тебе для примера:
http://ru.wikipedia.org/wiki/Обфускация
http://habrahabr.ru/post/137459/
Тоже устраиваюсь джуном, скинь все задания, которые тебе прислали
№337200-кун
>>337208
Не бро, абракадабру я прогнал, там задание на формочку регистрации и авторизацию
1. Write a listbox-style binary search for an ordered array of integers. Listbox-style means that you should return the index of the first item greater than or equal to the item being searched for; if all items are less, you should return the index of the last item. You are guaranteed that there is at least one item in the array.
2. Suppose you have an array of integers, both positive and negative, in no particular order. Find the largest possible sum of any continuous subarray. For example, if you have all positive numbers, the largest sum would be the sum of the whole array; if you have all negative numbers, the largest sum is 0 (the null subarray)
Please report how long did it take you to do these tasks. We will review and performance test your answers and let you know how it went.
Вот это на алгоритмы
>>337209
Точно, ты прав, я встречал такую хрень когда разбирался с цифровыми подписями и формированием хml отчетов через php скрипты, и первым делом подумал в ту сторону, спасибо за задания
>>337211
алсо как ты видишь они не совсем сложные, ну первое точно
по второму можешь глянуть этот линк и поймешь
http://forum.xakep.ru/m_1238569/tm.htm
>>337202
>Небось мухосранск с небольшим количеством фирм и большим числом никому ненужных быдлокодеров.
Лол, как я угадал.
Фирма из Новокузнецка оказалась.
>>337214
А ты раньше встречал эту кодировку? я к тому как ты догадался, что это зашифрованный текст именно в base64
вавп
>>337215
Сидел я на работе, это было 13 сентября 2013 - день программиста. В скайпе работники обсуждали какую-то херню. Одна девочка выложила вот это:
MjBmMjBjMjB0MjB6Qkb+MjB1MjA2MjB1MjB6MjB3MjBlMjBlMjA2MjBeMjB3MjBmMjBmMjBvMjBJ
MjBmMjBkMjB5MjBxMjBkMjB3MjB7MjB7MjBzMjBkMjBJMjBlMjBJMjBSMjB3MjBvMjA2MjBtMDA8
MDA9MjA2MjA2MjA2MjA2MjBmMjBjMjB0MjB6Qkb+MjB1MjA2MjBlMjBiMjB3MjBiQkb+MjB1MjA2
MjBgMjB5Qkb+MjByMjA2MjB7MjB3Qkb+MjB4MjA+MjBFMjBiMjBkQkb+MjB4MjBxMjBNMjBLMjA2
MjB3MjBkMjBxMjBlMjA/MjBtMDA8MDA9MjA2MjA2MjA2MjA2MjA2MjA2MjA2MjA2MjBFMjBvMjBl
MjBiMjBzMjB7MjA4MjB5MjBjMjBiMjA4MjBmMjBkQkb+MjB4MjBiMjB6MjB4MjA+MjA0QkZGMjA2
QkZRQkZ6QkZyQkZ5MjA2QkZ4QkZlQkZ3QkZ0QkZlQkZ1QkZ5QkZ5QkZ9QkZmQkZjQkZ1MjA3MjA0
MjA/MjAtMDA8MDA9MjA2MjA2MjA2MjA2MjBrMDA8MDA9MjBr
Помимо этого она выложила скрин (который сейчас 404 на фотохостинге), на котором и была эта надпись с поздравлением с днем программиста и словами что тому кто расшифрует этот текст подарят по-моему айфон или подобную поеботину.
Один из наших программистов сразу предположил что это скорее всего base64. Он вэб-кодер, так что с этой кодировкой мог сталкиваться, иногда она применяется в вебе для хранения двоичных данных прямо в html странице или js-коде, свиду похожа на случайный набор букв без пробелов. Я тогда тоже удивился как это ему так сразу удалось догадаться, однако оказалось что это не base64.
После этого случая когда я вижу какую-то ебень из букв без пробелов мне сразу приходит мысль: а не base64 ли это. Хоть какой-то опыт на работе приобрел, на хуй. Он даже пригодился на сосаче, лол. Почти полную уверенность что это base64 мне придал знак равенства в конце - по-моему это признак конца массива данных в base64.
И да, это сообщение никто из наших сходу не расшифровал, а более глубоко скорее всего никто и не брался, а если и брался, то втихую зафейлил.
И пользуясь случаем опять посылаю нахуй Абу за то что вакаба выдает сообщение "t.cо" вместо того что бы сказать что нехуй ставить ссылки в сообщение. Да и вообще ссылки это нормально, что за ебанатство. Пиздец, надо искать другую борду, это катится в полное говно и перспектив улучшений тут нет и не будет.
PS
Пиздец. Даже это сообщение отправить не удалось и пришлось в слове t.cо букву о делать русской. Ну полный пиздец. Аноны, как вы тут двачуете вообще? Несколько месяцев меня здесь не было и такой пиздец стал.
>>337225
>Mj Bj Qk
Скорее всего веб-дебильчики зашифровали текст каким-нибудь убогим Виженером. Попробуй ебнуть по тексту вероятностным криптоанализом, а то я свою библиотеку для частотного анализа проебал.
>>337234
Частотный анализ соснет и это очевидно в общем-то, если присмотреться к тексту. Я тогда в скайпе написал:
>Mj похоже левая инфа, типа какого-то префикса или команды, дальше идет параметр A или B, после которого еще один параметр.
Этими Mj текст нашпигован, ни один человеческий язык такой херни не имеет. Так что это похоже какие-то данные, которые хитровыебано закодированы алгоритмом очень похожим на сжатие, правда сжимающим хуёво, возможно и не сжимающим вовсе, но по виду он как сжатие.
Там еще был какой-то ключ шифрования в тексте сообщения на русском, которое сопустствовало этой кодированной херне. Гуглится легко теперь уже.
>>337170
Эта тема назвается синтаксический анализ. Ключевые слова: синтаксический анализ, лексический анализ, токенайзер, парсер, рекурсивный спуск (recursive descent), AST, абстрактное синтаксическое дерево.
Обрати внимание, что некоторые понятия имеют несколько названий:
токен = лексема
токенайзер = лексический анализатор
парсер = синтаксический анализатор
AST = дерево выражения
Вот пример теории: http://lord-n.narod.ru/download/books/walla/programming/Spr_po_C/24/24.htm
Она про разбор математических выражений, но суть та же. Что математические выражения, что разбирать BB-коды, что разбирать текст программы — это все работает по одним принципам.
Еще есть теория тут: http://citforum.ru/programming/theory/serebryakov/ но это очень хардкорный материал, наверно не для начинающих. Но можешь посмотреть.
Вот калькулятор на PHP, в котором есть токенайзер + парсер и который стоит это самое дерево методом рекурсивного спуска: http://ideone.com/4u4K5y . Наверно, его можно взять за основу, только выкинуть из него все лишнее.
Насчет дерева, вот теория: http://ru.wikipedia.org/wiki/Дерево_(структура_данных)
Пример дерева на PHP можешь найти в калькуляторе выше.
Давай начинать с простых вещей — с токенайзера. Попробуй написать токенайзер, с использованием регулярок, например, который разбивает входной поток текста на отдельные лексемы (токены). Токены могут быть 2 видов:
- просто текст без тегов
- тег (может быть открывающим, закрывающим, одиночным, может содержать аттрибуты).
Токенайзер должен заодно проверять правильность токенов: например, закрывающий тег не может содержать аттрибуты. И заодно проверять, существует ли указанный тег и допустимы ли у него указанные аттрибуты.
Токены, наверно, имеет смысл сделать объектами, это лучше чем массивы.
>>337173
О, хорошо, теперь все правильно. Я тебе советую еще глянуть вот этот раздел: http://www.php.net/manual/ru/regexp.reference.unicode.php
C помощью этих хитрых выражений можно написать например «цифра на любом языке» или «маленькая буква из любого языка».
>>337183
$wordsR = shuffle($words[$i]);
shuffle не возвращает новый массив, а перемешивает тот, который ей дан. Надо писать ппросто
shuffle($array)
В манауле, кстати это написано: http://php.net/manual/ru/function.shuffle.php в разделе возвращаемые значения.
>>337190
На самом деле, там конфиги объединяются в один и можно писать где угодно.
>>337197
Ну base64 — легко узнать, если ты серьезно изучаешь веб-кодинг, ты с ней столкнешься, например ей кодируются файлы в ссылках data:, заголовки MIME, некоторые клоуны ей кодируют параметры в адресной строке, и наверно еще что-то.
Но задание маленько заморочное, конечно, создавать виртуалку, настраивать, это минимум минут 20-30 уйдет.
>>337140
Не забудьте пропарсить вещи вида:
<a>text</b>text<b>text</a>text</b><b>
>>337225
> Почти полную уверенность что это base64 мне придал знак равенства в конце - по-моему это признак конца массива данных в base64.
Нет, это нули, если длина сообщения не кратна скольки-то байтам, то оно добивается нулями и появляется один или 2 знака равно.
В этом тексте повторяются группы по 4 буквы, так что наверно каждая такая группа кодирует один символ. Можно посчитать статистику по таким группам например командой:
cat | sed -r 's!(....)!\n\1!g' | egrep -v '^ $' | sort | uniq -c
Получается
4 MDA8
4 MDA9
2 MjA+
2 MjA/
2 MjA0
25 MjA2
1 MjA3
2 MjA4
1 MjAt
2 MjB0
4 MjB1
7 MjB3
4 MjB4
3 MjB5
4 MjB6
4 MjB7
2 MjBF
3 MjBJ
1 MjBL
1 MjBN
1 MjBS
1 MjBe
1 MjBg
6 MjBi
3 MjBj
6 MjBk
6 MjBl
6 MjBm
2 MjBr
2 MjBt
3 MjBv
3 MjBx
1 MjBy
2 MjBz
1 QkZ0
2 QkZ1
1 QkZ3
1 QkZ4
3 QkZ5
1 QkZ6
1 QkZ9
1 QkZG
1 QkZR
1 QkZj
2 QkZl
1 QkZm
1 QkZy
7 Qkb+
>>337245
Хотя не, не пробел. Пробелы обычно равномерно размазаны по тексту, а MjA2 идет сплошной полосой.
Слона всем, как учесть летнее/зимнее время? К примеру летом сдвиг по временному поясу -7 а зимой -8 делать?
ОП, подскажи пожалуйста, в каких местах надо выставлять кодировку и какую лучше всего, чтобы из формы в базу приходили нормальные слова, а не иероглифы?
>>337281
У базы и у таблиц должно быть выставлено utf-8. Также, когда коннектишься к базе задай кодировку соединения, выполнив запрос
SET NAMES utf8
>>337281
У базы и у таблиц должно быть выставлено utf-8. Также, когда коннектишься к базе задай кодировку соединения, выполнив запрос.
SET NAMES utf8
Алсо, пароли хорошо бы солить и хешировать.
>>337283
Спасибо, все получилось. Постоянно путаюсь с этой кодировкой.
Про шифрование паролей тоже наслышан, пока не стал применять, так как просто тестирую. Подойдет ведь обычное кодирование в md5 и последующее сравнивание введенного-перекодированного и хранящегося-закодированного?
Огромное спасибо, ОП, вроде получилось сделать связи и нужный селект. Посмотри пожалуйста, нормально делать именно так, или может есть какие-то более простые/правильные методы?
ОП, у меня снова подоспел вопрос. Допустим у меня есть вот такая форма:
<form action='admin.php?value=1' method='post'>
ФИО студента:<br />
<input type='text' name='fio_new_student', /><br />
Группа студента:<br />
<input type='text' name='group_new_student' /><br />
Логин студента:<br />
<input type='text' name='login_new_student' /><br />
Пароль студента:<br />
<input type='text' name='password_new_student' /><br />
<input type='submit' value='Отправить' /><br>
</form>
Можно ли изменить ее как-нибудь на:
<input type='text' name='fio_new_student', /><br />
Группа студента:<br />
<select>
<option>Группа 1</option>
<option>Группа 2</option>
</select>
Логин студента:<br />
<input type='text' name='login_new_student' /><br />
Пароль студента:<br />
<input type='text' name='password_new_student' /><br />
<input type='submit' value='Отправить' /><br>
</form>
Так вот, изменить ее таким образом, чтобы при нажатии кнопочки "Отправить" у меня в $_POST передавалось значение выбранной группы из выпадающего меню? Либо гуглю плохо, либо никак такое не сделать. Варианты реализации нагуглил только с помощью вынески выпадающего меню в другую форму, и при нажатии на нужную группу сразу передать ее в переменную.
>>337240
>shuffle не возвращает новый массив, а перемешивает тот, который ей дан
Ах, вот оно что. Энивей, а почему в задаче ты просишь переставить слова в обратном порядке а не в случайном. Мне кажется, речь Йоды больше похожа на рандомный порядок слов.
BTW Ну и хардкорная же задачка про числа прописью!
http://ideone.com/0D1E4M
>>337284
> Подойдет ведь обычное кодирование в md5
Нет. Во-первых, в этом случае видны одинаковые пароли, во-вторых, есть такая хрень как радужные таблицы (название-то какое):
https://www.freerainbowtables.com/en/tables2/
Там есть таблицы вроде такой: md5_mixalpha-numeric#1-9 — подбирает пароль к любым паролям из букв и цифр до 9 знаков. То есть почти все твои пароли за 10 минут подберутся.
Надо солить хеши, то есть генерировать случайную последовательность хитрых символов, вроде #ysd^&7gw:5f62, прибавлять ее к паролю и хешировать вместе. Естественно, у каждого пользователя должна быть своя рандомная соль.
Ну а вообще, в PHP5.5 добавляют стандартные функции для хеширования паролей (с солью и всем чем надо): http://habrahabr.ru/post/194972/ Ну пока 5.5 еще малораспространен, придется тебе ручками солить пароли.
>>337289
Совет: Чтобы не писать длинные имена таблиц, используй алиасы. Также, пиши ON для каждого JOIN отдельно (ради читабельности):
SELECT m.month_name, u.fio, ....
FROM users u
INNER JOIN months m ON i.monthid = m.id
INNER JOIN info i ON i.userid = u.id
...
Также, советую, пока не поздно, переименовать поля:
months.month_name → months.name (так как получается масло масляное)
userid → user_id
monthid → month_id
progulov_vsego → classes_skipped
progulov_po_nu → ??? не могу придумать
>>337289
Также, мне кажется, нет смысла держать таблицу с именами месяцев. Проще номер месяца хранить цифрой, а при выводе средствами Php заменять на название.
>>337320
Нехорошо, работать с числом как со строкой. когда у нас есть математика. Разбить число на группы по 3 можно, например, деля его на 1000 и округляя, пока оно не станет равно 0.
Тем более, что у тебя там код какой-то запутанный.
Конечно, тут еще есть хитрый хак, использовать explode(',', number_format($number)), но я думаю, лучше все же обойтись математикой.
А так, программа работает правильно.
>>337356
>Разбить число на группы по 3 можно, например, деля его на 1000 и округляя, пока оно не станет равно 0.
Вот до этого не додумался, вот и начал со строкой изъёбываться. Да что там говорить для меня и это вот
$lastTwoDigits = $number % 100
было откровением. Я такой когда это увидел, сказал "Ого-го".
>>337404
По моему, у меня это где-то было написано. Хотя сейчас не помню уже где. Может, под спойлером.
>>337404
А, нашел. В самом первом уроке написано же, ай-я-яй, я так и знал, что половину информации забывают сразу после прочтения.
>>333445
Сап, ОП. Проясни одну вещь. Вот есть у меня страница на ПХП. При открытии страницы в браузере отображается .php расширение в конце адресной строки. Чтобы его убрать, надо отредактировать htaccess. Помнится в вордпрессе URL любой страницы окончивался .html расширением. Это тоже редактируется в htaccess по сути? И ещё кое-что: вот есть несколько статей на сайте, доступ к которым осуществляется через GET-метод. URL имеет вид: название_страницы.php?id=666. Произвольные URL для каждой статьи (например чтобы было site_name.ru/articles/chitaemoe-nazvanie.html) настраиваются тоже через htaccess?
>>337427
Если правильнее говорить, то не только через htaccess, можно еще например через конфиг Апача. Да, это надо гуглить mod_rewrite — суть в том, что можно все URL, которые не соответствуют файлам на диске, перенаправлять на index.php и там уже анализировать средствами PHP.
> URL имеет вид: название_страницы.php?id=666
Отстойно, надо исправлять, а то поисковики не любят такие адреса.
Знающий анон поясни мне немного за хайлоад. Только недавно начал вести дела с хайлоад проектами и учиться в этой сфере, оптимизирую базку потихоньку, смотрю узкие места, кеширую там где можно и нужно.
Поясни вот за что, первое дай общих советов по оптимизации скриптов, чего стоит избегать, на что нужно обратить внимание и что реально знать.
Второе, более реальная проблема, есть один сайт, который пока не оч нагружен, но разрабатывался с учетом на высокую нагрузку, там очень много обращений к базе на главной, много картинок и js скриптов, все было оптимизировано и сайт грузился за пару секунд все это время, но неожиданно, пару дней назад стал дико тормозить, буквально до полторы минуты, при том, что потребляемый объем памяти и числа процессов на сервере не превышен, хоть и тоже скакнул. Людей там еще немного, во всяком случая пика посещаемости не наблюдалось. Прямо магия какая-то, сижу и не могу понять в чем дело.
Смотрел статистику получения данных в консоли хрома и там тоже сплошная магия, например один файл стилей весом 67кб получен в течении 83ms а другой в 6кб уже за 3.6s(секунд!), при этом все это время 3.6s описано как Waiting (я так и не понял чего он ждал). Далее иногда сайт грузиться в момент, а потом снова часами, хер пойми в чем дело, поясните по хардкору
>>337458
не хватает памяти и оно начинает работать через своп. Либо запускается сборщик мусора.
Попробуй поиграться с настройками веб-сервера и субд
мимоджавист
>>337458
> описано как Waiting (я так и не понял чего он ждал).
Ответа со стороны сервера.
Насчет сайта, скорее всего хостер просто добавил на тот сервер другие сайты, которые жрут ресурсы, вот тебе стало меньше их доставаться. У многих хостеров принят так называемыц оверселлинг, то есть продажа большего числа ресурсов чем есть на сервере.
Насчет хайлоада. Начинать надо с измерений и анализа. Меряй сколько времени выполнялась страница, сколько памяти ела. Удобно, например, поставить код в конце скрипта, который в случае, если потрачено больше X секунд или Y Мб памяти, пишет данные в лог.
Насчет Бд — то же самое, меряй число запросов, суммарное время выполнения, чуть что не так, пиши в лог, потом смотришь лог и разбираешься. Хорошо написанные запросы на хорошем сервере, как правило выполняются где-то за 1 мс.
Еще можно мерять число выбранных строк. Если ты тащишь из базы тысячи строк ради отображения простой странички, тут что-то не так.
Еще можно настроить в MySQL так называемый slow_log, она будет сама писать в этот лог медленные запросы.
Кроме правильных запросов, важны правильные настройки Бд. Сколько памяти выделить под те или иные буфера, сбрасывать ли данные на диск при каждой транзакции — эти настройки могут очень сильно влиять на скорость работы.
Читай логи ошибок. Если в скриптах ошибки, то сам понимаешь, гарантировать ничего нельзя, в том числе скорость работы.
Для оптимизации запросов надо научиться пользоваться командой EXPLAIN. Статьи ищи в гугле по фразе «MySQL EXPLAIN индексы», просто бери и читай все что там написано.
Для оптимизации PHP-кода можно использовать профайлер, например, расширение xDebug. Он может померять время и число вызовов каждой функции в твоем скрипте и увидеть, где проблемы. Просматривать результаты профайлера можно программой WinCacheGrind или веб-приложением WebCacheGrind (ставится на сервер, работает в браузере).
Бывает, что надо делать какие-то тяжелые запросы, и никак без этого не обойтись. В таком случае стоит их делать не при загрузке страницы, а раз в N минут по крону.
Также, можно использовать кеширование, но лучше бы научиться делать так, чтобы код и без него работал быстро (а не пытаться спасти этим плохой код), а добавлять кеширование когда к тебе повалят сотни тысяч пользователей.
На что обратить внимание: у начинающих кодеров, как правило, тормозит база данных, потому что они пишут хреновые запросы. У тех, кто пишет хорошие запросы, тормозит PHP-код, но это не такая большая проблема, так как PHP-код легко масштабируется (в отличие от базы).
Ну отдельные особо талантливые личности могут еще делать во время обработки запроса обращения к сетевым сервисам (которые могут ториозить) или большое число файловых операций (диск не резиновый). Еси ты логгируешь время выполнения разных частей сркипта, это будет видно.
Поставь на сервер оп-кешер, например, XCache. Он экономит время компиляции PHP-кода.
Для тестирования сайта под нагрузкой, научись использовать ab (apache benchmark) или siege. Ты увидишь, сколько пользователей одновременно держит сайт.
>>337458
Еще, кстати, освой команды линукса, такие как htop, iotop, iftop. Они позволяют увидеть, например, хватает ли памяти, хватает ли процессора, большая ли нагрузка на диск и сеть и какая зараза ее создает. Хорошо, например, запустить ab потоков так в 50 и смотреть, как реагирует сервер.
Естественно, это команды линукса, предполагается что основы пользования им у тебя есть.
>>337461
В Апаче вроде нет сборщика мусора, он на Си, а СУБД для отдачи статических файлов не нужна. А насчет настроек, автор вопроса скорее всего на шаредном хостинге и прав на их изменение у него нету.
ОП, проблема на пикрелейтед. Как сделать, чтобы подсветка синтаксиса была корректной?
>>337495
Вы посмотрите на эту пхпмакаку - хочет чтобы подсветка некорректного синтаксиса была корректной. Может за тебя еще и исправить?
>>337495
В heredoc маркер конца текста должен стоять в начале строки, без пробелов перед ним. Пример:
$text = <<<EOT
lalala
lalala
EOT; ← нет пробелов и других символов, кроме разве что точки с запятой
Пхп-кун, ответь на мой пост, пожалуйста.
Делаю небольшую программку: вводятся числа, некоторые данные считаются, все это заносится в шаблон rtf и так далее.
У меня такой вопрос: как лучше хранить эти самые числа. На данный момент у меня есть два списка: первый хранит названия для полей ввода (делаю в tkinter'e) а второй список, где собственно хранятся сами числа делается генератором по всем этим названиям, то бишь чтобы добавить новый элемент достаточно вписать в первый массив название. Так вот. Так норм или есть другие общепринятые методы? Потому что в шаблон я вставляю именованными элементами (например %(age)d) и приходится вручную сопоставлять элементы массива конкретному имени. Вот такая простыня.
>>337599
Я плохо честно говоря понял, о чем речь (какая-то GUI программа?), если речь о том, что поля формы в диалоге нужно периодически добавлять или менять, можно хранить информацию о них в файле, например XML или JSON — для работы с ними есть готовые библиотеки на многих языках.
> Потому что в шаблон я вставляю именованными элементами (например %(age)d) и приходится вручную сопоставлять элементы массива конкретному имени
Ну если я правильно тебя понял, то можно просто автоматически как-то парсить шаблон и извлекать из него все имена, тогда сопоставлять вручную не надо будет.
ОП-кун, вот калькулятор:
http://ideone.com/T4r0x5
В подсказки ни разу не заглянул ни к одной задаче, я могу считать себя программистом 2 lvl? :3.
Сап. Есть один скрипт (мой), который парсит одну хуйню, я написал ему шаблоны, которые хранятся в базе и достаются парсером. Далее мне надо эти шаблоны взять из базы, поместить в пхп код и выполнить в той базе, к которой будет подключен парсер.
Ньюанс: некоторые шаблоны содержат регулярные выражения.
Вопрос вот в чем: как мне блядь совладать со всеми обратными слэшами?
>>337631 пока сунул их в файл рядышком и тащу file_get_contents, но это нубство какое то, хочу в код запихнуть, может закодировать его как то? Или просто заменить "\" на "@@@huy@@@"...
>>337648
Сколько тысячь запросов в секунду обрабатываете?
>>337631
Я не понял, в чем проблема с обратными слешами? База данных их позволяет хранить. Ничего специально делать не надо.
>>337628
В регулярках внутри квадратных скобок [ .. ] надо экранировать только [ ] ^ - , знаки * / + = можно не экранировать (можно и экранировать, хуже не будет).
> else
> echo "Wrong input!"
> exit
Фигурные скобки где? если их не ставить, то к else относится только первая команда и такой код равносилен
else {
echo ....
}
exit
То есть exit оказывается за пределами else, а не в нем. Потому не надо пропускать фигурные скобки.
В остальном, все верно решено. Насчет 2 lvl, там же еще задачки есть после калькулятора, ты и их реши до кучи.
>>337631
Хотя я тут подумал, наверно ты просто не знал про экранирование данных при записи в Бд. Есди ты работаешь с устаревшими фунгкциями mysql_* то надо делать так:
$text = "'\\'<&"; // любые символы
$result = mysql_query($conn, "INSERT INTO t SET text = ".mysql_real_escape_string($conn, $text));
Если ты как правильный пацан используешь Pdo то просто используй плейсхолдеры:
$stmt = $pdo->prepare('INSERT INTO t SET text = :text');
$result = $stsmt->execute(array(
'text' => $text
));
И все бекслеши и специсмволы закодируются как надо сами собой.
А то, что ты делаешь — это плохо. Ты вместо того, чтобы почитать теорию, мануал, изучить общепринятые подходы выдумываешь свой кривой велосипед, из-за которого текст в твоей базе теперь не прочитать например через phpMyAdmin.
>>337677
оу оу оу полегче, ОПчик. В начале этого урока сказано, что кто решит задачи из этого урока, тот получает второй лвл. Нет, следующие-то я тоже конечно решу, и добавки еще попрошу, но 2й лвл то я уже щас хотел апнуть!
Насчет экранирования - знаю, ты говорил уже, но почему-то именно в этой задаче если их убрать, ничего не работает.
Говорит что-то типа undefined modifier, как будто не видит что всё это в квадратных скобках, я не знаю почему так.
а по поводу скобок фигурных, да косяк. Просто ехit я потом дописал, а скобки не добавил по невнимательности.
>>337702
> Говорит что-то типа undefined modifier, как будто не видит что всё это в квадратных скобках, я не знаю почему так.
Это потому что неэкранированный знак деления он принимает за конец регулярки, она же у тебя в слеши заключена и офигевает от того что там куча непонятных флагов идет после слеша.
> но 2й лвл то я уже щас хотел апнуть!
Ну тут такая история. Раньше калькулятор был последней задачей в учебнике. Так что апнуть ты можешь. Но учти, это не все, там еще задачи есть и есть ООП, который еще за поллевела считается.
А что, в пыхе нет моей любимой конструкции с сокращенным циклом И, ИЛИ?
var $переменная = $значение || $дефолт
Не хотеть ифы, функции и тернаропроблемы, у меня VOCAROO от этого
ОП запили мне про жизнь объектов, кеширование (не nginx а в функциях), хорошие практики.
inb4: на сайте не нашел.
>>337722
Операция есть, но результат ее - булево значение, а не один из параметров, так что обломись.
Можешь использовать
var $переменная = $значение ?: $дефолт;
>>337722
Нет. Deal with it.
Есть ?: но она только в 5.4 доступна.
>>337737
Что за жизнь объектов?
Кеширование применяется на высоконагруженных сервисах для снятия нагрузки с БД (так как кеш легко и дешево масштабируется, а БД - нет). Кеширование не всегда помогает, например плохо написанный код им не всегда можно выправить.
Кешировать можно на разных уровнях, можно кешировать HTML, вплоть до страницы целиком, можно кешировать массивы данных из БД. Что выгоднее, зависит от того, как часто меняется информация. Например, если страница дляразных пользователей выглядит по-разному или на ней много виджетов с меняющейся информацией, кешировать ее HTML целиком бесполезно.
HTML-кеширование хорошо подходит для статичесих или почти статических сайтов. Например, блог, в который нечасто пишут комменты и в котором 99% посетителей незалогинены (и видят одно и то же) или сайт на CMS со статьями — его можно кешировать в мемкеш прямо на уровне nginx, так что PHP-код даже не будет вызываться, yubyrc будет разбавать страницы прямо из кеша и скорость работы будет как у статического HTML-сайта (максимально высокая). Если же это не вариант, например много залогиненных пользователей, можно кешировать на уровне записей из БД.
Что хорошо кешируется? Сущности, которые не очень часто меняются (то есть читаются чаще чем изменяются) и определяются по id, например: данные пользователя 3456 (user:3456), список последних новостей (lastNews), число комментариев к посту 5643 (commentCountForPost:5643), сессии (session:gasdagdyagd7ad7a).
Что плохо кешируется? Данные, к которым редко обращаются, которые зависят от большого числа параметров (вроде результатов поиска, так как каждый ищет что-то свое и кеш будет бесполезен).
В чем подвох кеша? Ты обязан продумать все условия и зависимости, когда сбрасывается кеш, и не забывать его сбрасывать. Например, юзер поменял имя или email — надо сбросить кеш, юзеру подарили подарок — надо сбросить кеш числа подарков, отправили сообщение — надо сбросить счетчик числа сообщений, и так далее.
В чем еще подвох? Кеш — не база данных. Он может сброситься в любой момент и нельзя хранить в нем данные.
Если у тебя есть какая-то конкретная ситуация, можешь написать, посмотрим что делать, а то так трудно давать советы.
>>337799
когда уничтожаются, жизнь их в пределах одной функции или при закрытии функции они не уничтожаются а висят в памяти.
За кеширование благодарю, подробно написал.
>>337805
> кешировать на уровне записей из БД
подробнее если можно.
Хотет хорошо вникнуть в пхп, не просто хорошо писать код пользуясь встроенными функциями но и понимать какие лучше и что за ними происходит.
>>337805
Вообще, программист не должен этим заморачиваться и по идее все удаляться должно само. Объекты ведут себя как любые другие переменные (строки/массивы) и удаляются, когда на них не остается ссылок.
Там есть 2 системы: счетчик ссылок (уничтожает объекты без кольцевых ссылок) и сборщик мусора (уничтожает любые объекты). Описание есть в мануале: http://php.net/manual/ru/features.gc.php
> жизнь их в пределах одной функции или при закрытии функции они не уничтожаются а висят в памяти.
Если на них нет живых ссылок, например из других переменных, то уничтожаются.
Если тебя интересует потребление памяти, то надо не гадать, а мерять его в разных точках скрипта, например через memory_get_usage() и memory_get_peak_usage(). Это гоаздо полезнее чем вручную считать где там что освобождается.
>>337807
> подробнее если можно.
Ты с мемкешем работал? Если нет, поищи например где-нибудь на хабре статью про него и начни с теории. Просто иначе ты все равно ничего не поймешь.
А так идея в том, что мы кешируем строчки из БД в мемкеше, и первым делом, когда нужны какие-то данные, пробуем взять из мемкеша, а только потом, если там их нет, лезем в базу, за счет этого у ней идет меньше запросов и меньше нагрузка на нее. Стандартных функций для кеширования нету, это надо писать руками все.
>>337679 да все я знал, бро. Тут не одни ньюфаги сцаные спрашивают. Если бы подробнее прочитал мой пост с вопросом, то понял бы в чем сложность. \ используется для экранирования не только в базе но и в пхп. Соответственно, прежде чем сохранить экранированный sql в пхп его нужно еще раз заэкранировать (\\\\\\\\). Вот я и решил что лучше в закодированном виде хранить, а когда надо - раскодировал и выполнил.
>>337815
> Соответственно, прежде чем сохранить экранированный sql в пхп его нужно еще раз заэкранировать (\\\\\\\\)
Если ты используешь PDO и плейсхолдеры оно все само экранируется. Если ты используешь mysql_* ты и так наверно привык писать везде mysql_real_escape_string, так что не вижу никакой разницы: что сохранить в базе комментарий в котором могут быть теги, кавычки и слеши, что регулярку.
> Вот я и решил что лучше в закодированном виде хранить, а когда надо - раскодировал и выполнил.
ну так теперь если ты каким-нибудь phpMyAdmin или любой другой программой захочешь в базе поковыряться, ты там ничего не разберешь, а так были бы регулярки в исходном виде.
>>337816
>лучше в закодированном виде хранить в пхп файле
Я ещё одну решил, Опчик.
http://ideone.com/v4ywrg
ОП, у меня к тебе серьезный вопрос насчет выбора языка.
Мотивацией для меня стало написание своего первого сайта, ввиду большой распространенности выбрал пхп, но смущает большое количество негативных отзывов об этом языке. К тому же, насколько я понимаю, большинство скриптов современных сайтов выполнено на явескрипт.
В связи с этим вопрос: верен ли выбор пхп как первого вэб языка? или стоит предпочесть ему явускрипт(питон).
И еще такой вопрос: для сождания сайта использую apach+sql+php, будет ли эта же конструкция работать, если заменить php на js(соответственно переконфигурировать апач)? Заранее спасибо
>>337849
> большинство скриптов современных сайтов выполнено на явескрипт.
На яваскрипт пишут клиентские (работающие в браузере при загрузке страницы) скрипты. А на Php - серверные. Это не одно и то же. И в итоге тебе учить придется и тот, и тот.
Конечно, есть такая штука как node.js, которая запускает яваскрипт на сервере, но не думаю, что начинающему ее будет просто понять.
> для сождания сайта использую apach+sql+php, будет ли эта же конструкция работать, если заменить php на js(соответственно переконфигурировать апач
Нет. Чтобы выполнять JS на сервере, надо Node.JS а не апач.
> но смущает большое количество негативных отзывов об этом языке
А ты не читай отзывы несчастных ява-кодеров в /pr. Ты открой сайт с работой, например hh.ru или hantim.ru и посмотри число вакансий по разным языкам.
Питон — неплохой язык, но по моему он менее распространен и чуть посложнее PHP.
>>337838
Программа работает правильно. Совет:
> uksort($bills, "compareBills");
В таком случае проще использовать анонимные функции:
uksort($bills, function ($a, $b) {
...
});
Но тут сортировка по числам и можно взять krsort() с флагом SORT_NUMERIC (флаги описаны тут http://www.php.net/manual/ru/function.sort.php)
Если хочешь попробовать усложненную версию программы, добавь купюры номиналом 200 и 2000 (просто добавить их в массив не выйдет, если в банкомате 1×500, 3×200, 0×100 и надо выдать сумму 600р, этот алгоритм не сработает).
Дичайше плавится мозг от вроде бы простой задачки. Допустим, нужно реализовать механизм акции для какого-нибудь магазина. Менеджер в админке указывает дату начала и дату конца, а также условие, например скидка 10% от цен на определенную категорию товаров, например бухло. Т.е., допустим, 01.02.2013 один скрипт должен самозапуститься, пробежаться по базе и поправить цены. Другой скрипт, допустим 01.03.2013 все откатить обратно. Нагуглил про cron, но не вижу как он тут может помочь, скрипты-то не руками должны добавляться в админке хостинга, а в скрипте.
Приходит в голову такое решение - добавить в cron скрипт, который ежедневно проверяет таблицу 'акции' в базе. Если сегодня
=дата начала
/конца
- выковырять из поля сделать скидку
/вернуть как было
текст внутренних скриптов, запустить. Звучит ужасающе. Все правильно придумал?
>>337896
>пробежаться по базе и поправить цены
Когда ж вы все передохнете уже наконец, а?
>>337851
>Питон — неплохой язык, но по моему он менее распространен и чуть посложнее PHP.
А что насчет Ruby/Rails
>>337907
Тоже неплохой язык. Но там порог вхождения выше, чем в PHP.
>>337896
Нужно встроить код проверки в магазин, чтобы он при выводе страницы и в корзине как-то учитывал скидку. Например, проверял, подпадает ли товар под какую-то акцию, если так то скидка. Это самый лучший вариант.
А хранить скрипты в базе — быдлкодинг-стайл.
>>337896
Не надо нихуя в базе править.
>01.03.2013 все откатить обратно
Ебани таблицу акций, где будут указаны даты начала-конца акции, скидка и тип товара и используй эту таблицу для своего петушения. Править он блядь собрался скриптом каждый день.
>>337915
>чтобы он при выводе страницы и в корзине как-то учитывал скидку. Например, проверял, подпадает ли товар под какую-то акцию, если так то скидка
Хм, разве не логичнее один раз запустить примитивное "UPDATE товары
SET цена
=цена
*0.9 WHERE категория
=алкоголь
", нежели абсолютно любой заказ проверять на текущие акции, которых вообще может и не быть?
>А хранить скрипты в базе — быдлкодинг-стайл.
Ну в принципе это можно и обойти и хранить в базе условия(скидка, категория), а скрипт на ходу составлять из них.
>>337928
>используй эту таблицу для своего петушения. Править он блядь собрался скриптом каждый день.
Почитай внимательно - не править, а проверять нет ли сегодня начала или конца каких-то акций. Если начало - да, править, если конец - откатить и удалить эту акцию вообще. О каком петушении ты говоришь?
>>335464
>>335456
Попробовал слегка допилить всё это дело. Убрал правила для пароля и логина, оставил только максимальную длинну имени и минимальную - пароля. Немного переделал отображения, теперь введенные данные не пропадают при повторном выводе формы, если я в первый раз неправильно заполнил каие-то поля. Добавил капчу, отображается при создании постов/комментариев для анонимных пользователей и после некольких зафейленых попыток авторизироваться. Капчу делал сам, нужно будет на ещё доделать, либо взять уже готовый сервис типа reCaptcha.
Добавил поля с csrf-токенами к формам. Разлогин сделал через POST, вроде читал, что не рекомендуют передавать токены через GET.
Ещё добавил поле c 'honeypot captcha', прочитал про неё где-то на хабре, что скажешь, юзать этот метод имеет смысл?
Ну и на всё это у меня ушло реально дохуя времени, нужно будет както величивать работоспособность.
>>337956
>Почитай внимательно
>01.02.2013 один скрипт должен самозапуститься, пробежаться по базе и поправить цены
Все написано вполне однозначно.
>UPDATE товары SET цена=цена*0.9 WHERE категория=алкоголь
Править подобным образом - глупость.
>нежели абсолютно любой заказ проверять на текущие акции, которых вообще может и не быть?
Никаких проблем с этим быть не должно. Сомневаюсь, что у тебя сотни запросов в секунду будут, чтобы думать об оптимизации, тем более такой топорной. Профиты очевидны - акции обновляются автоматически, легко редактируются и удаляются, сохраняются первоначальные данные, чтобы не проебаться со стоимостью товара, что может быть критично.
>>337966
Профит в том что иногда надо написать 2 цены например
1000 (зачеркнуто) 900 — скидка 10% на X в этом месяце!
Хочу изучить программирование (и устроиться работать кодером! и съебать в таиланд!), но боюсь обнаружить что я непригоден для этого из-за гуманитарности/тупости и что придется похоронить мечту работать по профессии программиста вместо грузчика/кассира.
Что делать, посоны?
>>337971
>боюсь обнаружить что я непригоден
Ну заебись вообще. Как ты это обнаружишь, если даже не попробуешь? У тебя выхода нет. Берешь полгода, ебашишь, пробуешь устроится в говноконтору, поешь говна, пошлешь всех нахуй, найдешь другую говноконтору и так далее.
>>337975
Не слушай его, я так пробовал. Только рак спины заработал и веру в людей потерял. Некоторые вещи лучше не нечинать и не пробовать, чтобы потом всю жизнь об этом не жалеть.
Посоны устроился в говноконтору джуном, но на последнем собеседовании мне заявили что не будут платить боб ла до тех пор пока не начну приносить пользы. Прошел тестовое, не без ошибок но все сделал, и сегодня дали такой странный оффер. Слать их нахуй или подождать с месяц? Боюсь что меня кинут, пообещали давать реальные задания и все такое
>>337985
Скорее всего кинут. Видимо, им нужны работники, но только бесплатные.
на сайте в разделе "строки" дошел до задачи "на словах ты лев толстой", бла идея заморочиться и решить ее через массивы(создать массив с маской из позиций требуемых слов, прогнать через него все пять массивов, полученные данные собрать в переменную, а потом ее вывести), но подумал что это слишком громоздко и тупо вывел через echo {$word1[2]} {$word2[4]} и т.д. ОП, не подскажешь какое решение наиболее верно? Выбрал второе исходя из быстродействия: то что содержит меньше команд быстрее выполняется
>>337958
Анон, не забывай прикладывать ссылку на гитхаб. У нас же тут анонимная доска, я еле нашел адрес твоего гитхаба в истории.
> Ну и на всё это у меня ушло реально дохуя времени, нужно будет както величивать работоспособность.
Может это потому, что ты начинающий и пока пишешь не спеша.
> Ещё добавил поле c 'honeypot captcha', прочитал про неё где-то на хабре, что скажешь, юзать этот метод имеет смысл?
Имеет. Помогает против тупых ботов, которые не понимают CSS, а просто извлекают форму из HTML-кода и заполняют ее спамом. Я как-то применял на одном сайте именно против таких ботов (они не ориентируются на какой-то один сайт, а просто обходят подряд например миллион самых посещаемых сайтов).
Важный момент: когда ты что-то хранишь в сессии, будь готов к тому, что данные могут удалиться. Например, юзер открыл форму постинга, 30 минут писал комментарий, на сервере сессия удалилась, токен в ней тоже. Юзер постит форму, проверка токена не срабатывает, в этом случае надо не падать или терять данные пользователя, а просто отобразить форму повторно, написать что прошло слишком много времени, и попросить отправить ее заново. Ну или не хранить токен в сессии.
Еще важный момент: помни что юзер может открыть несколько вкладок сайта и все они используют общие куки и общую сессию. В частности: открывается первая вкладка, генерируется код капчи в сессии, отображается капча допустим 12345. Открывается вторая вкладка, генерируется новая строка капчи (89098), старая строка в сессии затирается и не сработает.
Чтобы этого избежать, делают так: для каждой капчи генерируют уникальный captcha_key, и хранят данные для каждой капчи отдельно: $_SESSION['captchas']['sdgyadyadtf'] = 12345; Ну и конечно надо периодически чистить массив если там накопилось много капч.
> Разлогин сделал через POST, вроде читал, что не рекомендуют передавать токены через GET.
Не обязательно. Разлогинивание можно делать через GET (и почти все так делают, например вконтакте). Нехорошо через GET делать методы, которые удаляют или модифицируют информацию на сервере, например постинг поста, удаление поста.
>>337958
> $ip = $_SERVER['REMOTE_ADDR'];
> if(isset($_SESSION[$ip])){
> return $_SESSION[$ip]['failsCounter'];
> }
Это не будет работать. Ведь бот-переборщик легко может очищать куки перед каждой попыткой, тем самым создавая новую сессию. Надо перенести этот код в модельку и переделать на работу с БД. Ну вообще хорошо бы использовать не БД, а что-нибудь полегче вроде мемкеша, но у нас тут его все равно нет.
> $_SESSION['csrf'] = $token; //if cookies are disabled
То же самое. Ты похоже, не понял, как работает сессия. А работает она так:
- Если у пользователя нет куки PHPSESSIONID, или она указывает на несущесьвующую сессию, то PHP генерирует новый id сесссии, выставляет эту куку, создает новую сессию на сервере (по сути, создается файл в /tmp), создает пустой массив _SESSION
- Если кука есть и валидная, то PHP загружает данные сессии из соответствующего файла в $_SESSION.
- После завершения скрипта данные из _SESSION сериализуются и сохраняются в файл сессии
- Раз в 15 минут по крону неактивные больше N (по умолчанию 24) минут сессии удаляются с сервера. Активность определяется датой модификации файла, то есть временем последней записи в него.
Вся эта система не работает без поддержки кук клиентом, в этом случае каждый раз генерируется новая пустая сессия.
CSRF токен стоит либо хранить в куках, либо в сессии (но не там и там сразу), либо генерировать из части IP адреса, но тут могут быть свои проблемы с динамическими IP, куки наверно лучше. Хотя при использовании IP все будет работать даже без поддержки кук в браузере. Django по умолчанию хранит токен в куке csrftoken, Yii тоже использует куки.
> if ($_SESSION['isCaptchaRequired'] == true){
Обходится очисткой кук (сессия тоже очистится).
> Application/Core/Auth.php
> $remember = false
> if ($remember == 'on'){
Было бы логично использовать false и true, а не false и 'on'
> Application/Core/CSRF.php
> public function chekToken($token)
> if ($token == $realToken){
$realToken может быть false, если токена нет в куках/сессии. Тогда если $token тоже пустой, равенство может сработать. Плохо. Надо сделать проверку что токен существует. Та же ошибка тут:
> if ($captcha == $realCaptcha){
Если сессия пустая, $realCaptcha = false и пустая строка капчи пройдет проверку (в PHP вроде бы '' == false).
>>337958
> public function getPost($object)
Эта функция ставит любые свойства объекта даже не проверяя есть ли они у него. Не, нехорошо. Лучше в объекте тогда сделать метод loadFromArray() и там присваивать только те свойства, которые есть в объекте. Такие вещи, как csrf или honeypot — не часть объекта Comment/Post, не надо их в нем хранить, не надо их проверять в модели, а лучше проверять где-нибудь в контролллере или отдельном классе.
> <input type="hidden" name="name" id="add-name" value="<?=$this->h($auth->getName());?>">
Это значение юзер легко может поменять, ненадежно же?
> $auth = new Core_Auth();
> $csrf = new Core_CSRF();
Эти объекты лучше не создавать в вью, а передавать откуда-нибудь. Например, из базового контроллера (так что они будут присутствовать в любом вью).
Также, еще подвох: после ошибочной попытки ввода капчи надо генерировать новую. После удачной — удалять код капчи из сессии.
>>337958
> <img src='<?=Config::getBasePath()?>/captcha/create' />
/ в конце тега не нужен.
Адрес картинки плохой, так как он всегда постоянный. Браузеры или прокси могут легко закешировать такую картинку даже если ты выставишь запрещающие заголовки. Лучше добавить в путь уникальные символы вроде /captcha/create/f67fsd7sr (можно использовать captcha_key если он есть)
>>338003
Простое решение вполне подойдет. Что касается ыбстродействия, не думаю что там есть хоть какая-то заметная глазу разница.
меня немного вымораживает, когда при форматировании кода по ссылке в оп посте мы получаем
if ($domain == "sait.ru") {
print "Disallow: /zapis.php
";
}
тоесть перенос "; на следующую строку, хотя в присвоении данных переменной этого нет. это как-то можно выключить?
>>338021
Может у тебя какие-то символы в строке были? Я попробовал сейчас вставить код
<?php
if ($domain == "sait.ru") {
print "Disallow: /zapis.php";
}
(без отступов), он просто добавил отступ перед print и все. Содержимое строки он по идее трогать не должен.
Единственное, ; переносится если она лишняя. Например, тут:
if (...) {
...
};
; после скобки перенесется на новую строку так как она не нужна.
и почему при форматировании первого if 4 пробела поставились, а при втором нет?
>if ($key == $pass or $key == $passgeneralall) {
if ($key == $passgeneralall) {
$this_is_admin = "yes";
$log="admin";
}
if ($key == $pass) {
$this_is_admin = "m";
$log="m";
}
}
>>338024
Ты маркер <?php перед кодом не забыл поставить? Если поставить, то все как надо форматируется.
>>337896
У нас вот так зделоли.
Запросы присылать или сам напишеш сам напишит
>>337978
>рак спины заработал
Никак не связано.
>веру в людей потерял
Им нельзя верить изначально.
>Некоторые вещи лучше не нечинать и не пробовать
Если "некоторые вещи" подразумевают под собой "выпить литр бензина", то безусловно. В других случаях единственный способ проверить, надо или нет - сделать.
>>337971
Братишка, я вот тоже сейчас все силы бросаю на изучение программирования и тоже боюсь а вдруг я никому нахуй не буду нужен без диплома. Что ж я по крайней мере попытаюсь устроиться во все конторы своего города.
>>337971
Ничего не делать, очевидно же. Вдруг ты действительно не пригоден?
>>338074
Диплом нужен для выполнения госзаказов. Отчётность.
>попытаюсь устроиться во все конторы своего города
Это не все конторы, а те, куда никто не хочет идти. А так как сами они прекрасно об этом знают, то и фраза:
>а вдруг я никому нахуй не буду нужен
Окажется верна! Гораздо страшнее, если ты им будешь нужен, тогда мы больше о тебе (и от тебя) ничего не услышим.
Т.е. искать надо долго и тщательно, и диплом тут поможет мало, а наличие его отсутствия - так и вовсе ни при чём.
>>338091
>попытаюсь устроиться во все конторы своего города
Это не все конторы, а те, куда никто не хочет идти. А так как сами они прекрасно об этом знают, то и фраза:
>а вдруг я никому нахуй не буду нужен
Окажется верна! Гораздо страшнее, если ты им будешь нужен, тогда мы больше о тебе (и от тебя) ничего не услышим.
Нихуя не понял джпег.
recursive-descent калькулятор на питоняше http://ideone.com/YzGnNP
>>338107
Давно пора было влючить спеллчек в виме, спасибо.
>>338097
Выражение вроде - - - - 2 не поддерживается? А так, да, работает, да еще и на всяких генераторах с итераторами.
ОП, в каждом твоем треде просто масса полезной информации и множество интересных ответов. Причем развернутых, повествующих простым языком. Так вот. Все это может очень пригодится как и мне в будущем, так и всем другим. Ты не задумывался о создании какой-либо базы знаний, куда будешь писать ответы на наиболее часто задаваемые вопросы, когда будет настроение - писать о том что и как надо делать, а что нет. В общем то место, где будут действительно полезные знания. Треды со временем уплывают, а искать все это и вспоминать даты очень проблематично. Может можно как-нибудь реализовать хотя бы наиболее частые ответы на вопросы, статейки? Спасибо тебе за все, ты очень хороший человек, что помогаешь нам во всем этом разобраться.
>>338132
Да не знаю, это нереально наверно все упорядочить. Я не представляю, сколько времени нужно чтобы перерыть архивы 30 или сколько там их было всего тредов.
Часть информации я собираю в пасты (несколько есть в разделе «Ооп и пасты» на сайте).
>>338011
Ага, то есть в сессии лучше хранить только недолгоживущие данные, типа капчи,например, а всё остальное - либо в куках, либо в бд, иначе, если я залогинюсь и пойду на полчаса гулять с собакой, то логин может слететь?
И как тогда быть с пользователями, у которых куки отключены? Вроде ж пхп умеет, при таком раскладе, передавать идентификатор сессии через URL.
>>338144
> И как тогда быть с пользователями, у которых куки отключены?
Без кук на половине сайтов вроде вконтактика ты не авторизуешься. думаю, такие пользователи не удивятся. Некоторые сайты, вроде яндекса умеют определять отсутсвие кук (они ставят тестовую куку и при логине проверяют ее наличие) и пишут сообщение об ошибке. Можешь сделать так же, если хочешь.
> Вроде ж пхп умеет, при таком раскладе, передавать идентификатор сессии через URL.
Он умеет при выводе страницы подставлять идентификатор в ссылки. Но во-первых, это кривой ненадежный костыль, во-вторых, это небезопасно так как при переходе на другой сайт, или загрузке любой внешней картинки URL (с идентификатором сессии) передается в реферере. Ни в коем случае не включай эту настройку. А, и еще при таком способе можно сделать атаку фиксации сессии: http://www.securityscripts.ru/articles/PHP/session-fixation.html
> иначе, если я залогинюсь и пойду на полчаса гулять с собакой, то логин может слететь?
Верно, потому надо использовать еще и куки. Или только куки.
Сап, програмач.
Разъясни по хардкору.
Битый час пытаюсь вникнуть в суть, курю холивары. до сути не дошел.
Собствено сабж - чем плох GOTO? DВ чем блять?
Все холивары сводятся к ко-ко-ко нечитаемость кода.
Ко-ко-ко не нужен, можно без него.
А нахуя без него, лепить лишние овер9000 конструкций, когда въебал один goto и отправился нахуйк нужному участку кода?
Вот и в PHP 5.3 ввели goto.
Короче. Гуру, разъясните же, в чем дзен?
>>338211
Разъясняю. goto обычно используют люди, которые не умеют разбивать код на функции, не умеют правильно использовать циклы, а лепят код одной длинной портянкой. В таком коде, естественно, без goto вообще ничего работать не будет. Видимо, для них его и добавили. В PHP много странных вещей.
Потому ичпользовать goto = поощрять быдлокодинг. Правильнее научиться писать аккуратный структурированный код.
>>338211
Алсо, приведи пример, где по-твоему без goto никак не обойтись, а мы попробуем рассказать где ты неправ.
>>338224
Плюс
http://programmers.stackexchange.com/questions/154974/is-this-a-decent-use-case-for-goto-in-c/154980#154980
Кстати "обойтись без goto всеми возможными способами всегда" это уже религия, по типу "смоделировать любую возможную ситуацию в ООП терминах". То, что весь основной control flow должен быть структурным - никто особо и не спорит. Но иногда goto может быть наилучшим решением для ситуации. Пример - goto отлично подходит для описания конечных автоматов, простого switch может быть недостаточно и он может делать код запутанным.
>>338227
> Пример - goto отлично подходит для описания конечных автоматов, простого switch может быть недостаточно и он может делать код запутанным.
Насколько я знаю, такие вещи генерируются из набора правил, а не пишутся руками, так что этот пример не считается.
>>338231
Почитай:
http://www.literateprogramming.com/adventure.pdf
"By the way, if you don't like goto statements, don't read this."
Конечный автомат безусловно можно писать руками и, как ни странно, семантика goto эквивалентна семантике state transition. Никакой лапши, никакого "плохого дизайна".
То, что что-то "генерируется" вообще иррелевантно. Я могу PHP генерировать из Haskell и весь твой традиционный control flow(циклы, условные операторы) в Haskell коде не будет виден вообще.
Если взять в качестве примера генератор парсеров(это тоже такая вещь, которая "генерирует" код по декларативному описанию), то в промышленных компиляторах, например, это не используется и парсер пишется и оптимизируется вручную.
О пользе goto на низком уровне я вообще молчу, там она очевидна.
Кстати, известная работа Дийкстры против goto имеет исторический контекст. Она была призвана перетащить прикладных программистов того времени на струтурное программирование. Я выше писал, что код должен быть в основном структурным, но мне не нравится такое религиозное отношение к вещам, осмысленное применение которых очень зависимо от контекста.
>>338233
>> 1) это не PHP
Твое первоначальное заявление было о ненужности goto, а не о goto в PHP.
>> 2) разработчики ядра линукс своеобразные люди. Они и на ООП переходить не желают.
Не нужно пытаться свести технический аргумент в социацльную плоскость. Причины, почему там используется goto были приведены и эти причины серьезны. На самом деле, на низком уровне, таких причин чудовищное количество.
>>338224
Без goto всегда можно обойтись. Это не аргумент против него, потому что обойтись можно без всех высокоуровневых языков например.
>>338232
Я ни раз в PHP не встречал необходимости в goto.
> Конечный автомат безусловно можно писать руками и, как ни странно, семантика goto эквивалентна семантике state transition. Никакой лапши, никакого "плохого дизайна".
Сомневаюсь. Если ты пишешь огромную функцию на 2000 строк, это нечитаемая лапша с высокой вероятностью ошибок например из-за повторного использования переменных.
> О пользе goto на низком уровне
Как может быть «низкий уровень» на PHP? Байткод руками писать что ли? Пиши на Си лучше.
> То, что что-то "генерируется" вообще иррелевантно.
Что за бред. Сгенерированный код никто не будет читать и править, потому в нем можно писать что угодно. А в обычном — нет.
> то в промышленных компиляторах, например, это не используется и парсер пишется и оптимизируется вручную.
Да ну, сомневаюсь. Это долго, скучно и неинтересно и непонятно зачем нужно.
>>338238
>> Я ни раз в PHP не встречал необходимости в goto.
В PHP она почти и не может возникнуть. Человек который на PHP пишет код с goto умрет с голоду, потому что работать он не сможет в принципе.
>> Что за бред.
Ты не понял, читай ниже.
>> Да ну, сомневаюсь.
А вообще-то не спорю с тобой, а говорю, что это так. Как пример - любой компилятор C++. Это просто пример того, что иногда генерация чего-то может не подойти. В частности из за производительности результирующего кода.
Кстати механизм классов часом не на goto основан?
>>338238
>Я ни раз в PHP не встречал необходимости в goto.
Мало программистов вообще встречают такую необходимость. 90% занимаются написанием примитивного говна вроде веб-сайтов.
>Если ты пишешь огромную функцию на 2000 строк, это нечитаемая лапша с высокой вероятностью ошибок
Да, но эта лапша может очень быстро работать. Впрочем, программистам на ПХП таких задач не попадает.
>>338242
> Да, но эта лапша может очень быстро работать.
Расскажи нам пример такой задачи. Пока я увидел ссылку на пример из ядра линукса, ссылку на тех еще велосипедистов разработчиков из windows и все.
Ты ведь не думаешь, что программы тормозят из-за вызовов функций и оптимизируются объединением кода в один большой кусок кода с goto?
>>338244
>Расскажи нам пример такой задачи.
Тестер стратегий например.
>Пока я увидел ссылку на пример из ядра линукса
Этого уже более чем достаточно для примера. Мир не ограничивается веб-сайтами, которые ты пишешь. В конце концов они крутятся на том же линуксе в итоге.
>Ты ведь не думаешь, что программы тормозят из-за вызовов функций и оптимизируются объединением кода в один большой кусок кода с goto?
Думаю. Объединение (или разбиение) функций и использование гото давало где-то процентов 5-15% к скорости, плохо помню уже. инбифо: не надо мне рассказывать какие есть еще другие более эффективные способы оптимизации, я их получше тебя знаю
>>338248
Перейдя с PHP на Си++ ты получишь гораздо больший выигрыш в скорости, чем использованием goto.
>>338249
Я и не пишу на PHP и вообще его не знаю, мимокрокодил, заглянул в вашу веб-парашу. Кстати, вам же тоже сделали гото в пхп. По-началу его не было, видимо создатель повелся на стадный инстинкт ненависти к гото, а потом, после многих лет и практики поняли что гото нужен, а дейкстра просто был в истерике, а программисты, пошедшие за ним - просто тупое стадо. Вам и ООП завезли недавно. Еще бы статическую типизацию и язык станет годен для разработки больших проектов.
>>338253
Ну вот, а мы тут вообще-то обсуждаем почему не нужен goto именно в PHP. Подозреваю, его добавили чтобы проще было вычислить быдлокодера или сишника.
>>338254
>Подозреваю, его добавили чтобы проще было вычислить быдлокодера
Уже сам ПХП детектирует быдлокодера, так что в дополнительных средствах нет надобности на самом деле. Можно детектировать быдло разве что - не использует гото там где он бы помог - значит быдло, не имеющее своих мозгов и ведущееся за стадом.
Но конечно реально введение гото это признание отсоса Дейкстры и тем кто за ним последовал.
ОП, можешь объяснить в чем суть?
http://viper-7.com/YXiphB
http://viper-7.com/DyQ4LU
Прежде всего непонятно, почему перезаписанный private метод в первой пасте вызывается из родителя, но перезаписанный protected метод - из потомка.
Могу предположить, что учитывая то, что test() вызван в контексте родителя, а private методы в отличие от protected видны только в контексте класса, где они определены, он не может "подтянуть" его в область видимости из потомка, но всё равно какая-то путаница в голове.
>>338257
private методы можно вызывать только из того же класса где они определены. «Из того же класса» значит, что код вызова должен находиться в том же самом классе (где стоят точки: class A { .... } ), и никакие трюки со static:: не будут (и не должны) работать.
О чем тебе PHP и пишет:
Fatal error: Call to private method C::shout() from context 'A' in /code/YXiphB on line 6
Ты пытаешься вызвать приватный метод класса C не из этого класса, а из другого места в коде.
Обычно в PHP каждый класс пишут в своем файле. Получается, тогда приватный метод можно вызвать только из того же файла, где он определен. Удобно.
Идея с private/protected — это разграничение ответсвенности. Другие классы не имеют права лезть внутрь класса A, если он это запретил, и соответственно не могут испортить его внутреннее состояние и вызвать баг.
> почему перезаписанный private метод в первой пасте вызывается из родителя
Невозможно перезаписать private метод так как он принадлежит только одному классу. C::shout и A::shout это разные, не связанные друг с другом методы.
Задачка про считалку.
http://ideone.com/5c0HD6
Опчик, так правильно?
>>338320
Нет, у тебя ошибки в программе. Если мы берем 7 человек и 4 слога, должны остаться места 2, 3, 7. А у тебя — выходит по-другому: http://ideone.com/0hZTV2
Алсо, алгоритм какой-то усложненный. Смотри, можно проще. Мы можем просто сделать переменную «номер человека который выйдет», и увеличивать ее на $step с обработкой переполнения. Счет с обработкой переполнения можно обработать например через операцию %:
echo (2 + 1) % 4; → 3 // результат всегда будет < 4
echo (2 + 3) % 4; → 1
echo (2 + 6) % 4; → 0
А как удалить N-й по счету (не по ключам) элемен массива? Ну даже не знаю, есть такая функция array_splice, неужели она это может?
ОП, посмотри сюда, пожалуйста.
Есть чужой хостинг. На нем:
мускуль на апаче, схема и таблицы в UTF-8;
там же пхп5.3 с mb_internal_encoding() тоже UTF-8;
Читаем через PDO кирилицу, она приходит в аскии. И, соответственно, ее strlen() равен количеству символов, а не ожидаемому кол-ву байт. Хоть срись.
На локальном хостинге все нормально, но он умер. Где еще искать, кроме как не в кодпейджах мускула и пхп? Отдельной настройки для ПДО не знаю, хотя подозреваю именно его.
Завтра поразвлекаюсь с чтением через mysql_, но вдруг ты знаешь.
>>338440
Ипать колотить, я лох. Пол-ночи возился, сдался, задал вопрос и тут же нашел как надо:
В аргумент конструктору ПДО надо добавить ';charset=UTF8'
>>338260
Ясно, вроде прояснилось немного.
>Обычно в PHP каждый класс пишут в своем файле.
Прямо каждый или всё-таки класс и его наследников?
Еще вопрос, раз уж эта тема всплыла. Я тут неспешно пописываю кошек-мышек и в который раз встал вопрос о предварительном планировании архитектуры. Если это громкое слово, конечно, можно употреблять в контексте такой мелочи. Где-то на полпути пришлось переделывать структуру классов, когда их пять-шесть штук это не критично, но если, дай бог, буду писать что-то серьезное - это будет фейл былинных пропорций.
Ты же наверняка продумываешь архитектуру до начала написания приложения, особенно если не приходилось встречаться с подобной задачей до этого, да? Поделись секретами мастерства :3 Какой подход, какие тулзы (UML там, или карандаш с листом), как уменьшить вероятность объеба?
Вообще, afaik, архитектор приложения - чуть ли не самая высокая должность для программиста, но если приложение простенькое, пишется в одно рыло, то любой кодерок отчасти должен выполнять его функции. Вот и интересно очень. Предполагаю, что у Зандстры про это должно быть, только-только начал его читать. Ну и у Макконелла помню много на эту тему было, я как-то проглядел не особо вчитываясь, надо будет вернуться.
>>337722
Ващето можно слегка изъебнуться, хотя short circuit lazy evaluation в пыхе не такой изящный, как в том же js или рубях.
$b = '';
$a = $b;
empty($a) and $a = 'vocaroo';
var_dump($a); //vocaroo
$b = 'ebinxdd';
$a = $b;
empty($a) and $a = 'vocaroo';
var_dump($a); //ebinxdd
Но есть подводные камни - empty() приводит к булеву значению, т.е. 0 тоже будет считаться пустой переменной.
Если же использовать isset(), то пустая строка вернет true.
>>338470
> Прямо каждый или всё-таки класс и его наследников?
1 файл = 1 класс. Вот например Yii, можешь сам убедиться: https://github.com/yiisoft/yii/tree/master/framework/base
Это позволяет избежать бардака.
> Я тут неспешно пописываю кошек-мышек и в который раз встал вопрос о предварительном планировании архитектуры.
В таких задачках на ООП надо просто правильно выбрать объекты, какие у них будут свойства и методы и как они взаимодействуют, и все. Со временем научишься.
Советую потом код показать, вдруг ты там что-то навелосипедил.
> это будет фейл былинных пропорций.
Это еще называется рефакторинг.
> Ты же наверняка продумываешь архитектуру до начала написания приложения
Да это не так часто нужно. Ну смотри: если проект на фреймворке/CMS, пишем как принято в этой CMS. Если проект большой и начат до меня, пишем как в нем принято. Есть общепринятые подходы (паттерны) для типовых задач, есть готовый код чуть ли не на все случаи жизни и есть MVC. Потому именно продумывать архитектуру приходится редко, но если надо, то обычно ограничиваюсь листочками бумаги. UML — это, например, вариант для какой-то официальной документации.
Обычно архитектуру приходится продумывать (не мне лично, а вообще) в тех случаях, когда стандартных решений нет или они не годятся. Например, в хайлоаде. Например: был маленький проект с 1000 пользователей, все было хорошо, стал внезапно популярен, число запросов выросло, сервер дымится, база трещит, надо срочно что-то делать. Вот тут нужно продумывать архитектуру, что сделать чтобы можно было масштабироваться. Или надо организовать поиск по товарам с кучей разных фильтров и категорий. Или какой-то раздел на сайте тормозит и глючит. И обычно «архитектура» подразумевает именно такое.
А если у тебя маленький сайт или блог, на который заходит 100 человек в день, архитектура в общем-то не принципиальна.
Если ты начинающий, я советую как можно меньше придумывать велосипедов и как можно больше смотреть, а нет ли готовых библиотек/фреймворков для таких вещей и использовать их.
Если тебе интересно почитать именно про архитектуру больших проектов, вот, читай: http://www.insight-it.ru/highload/
> Вообще, afaik, архитектор приложения - чуть ли не самая высокая должность для программиста
Архитектор вообще требует немалых знаний в самых разных областях и опыта. А умение правильно написать классы, это не архитектура, а скорее базовые знания, которые должен иметь любой джуниор.
>>338470
>empty($a) and $a = 'vocaroo';
Плохой код, лучше писать более очевидно:
$a = empty($a) ? 'vocaroo' : $a;
Тут сразу по началу строчки видно что мы что-то присваиваем в $a.
> empty() приводит к булеву значению, т.е. 0 тоже будет считаться пустой переменной.
Обычно так и требуется.
> Если же использовать isset(), то пустая строка вернет true.
Лучше использовать явную проверку на null: $a === null
>>338470
Кстати, если ты хочешь научиться архитектуре MVC и написать с нуля веб-приложение, у нас есть задачка написать борду.
Также, у нас есть задачка на фреймворки - сделать свой аналог rghost на микрофреймворке.
Ну и еще есть задача «Напишите REST-сервис генерации превьюшек для изображений» в последнем уроке в учебнике, но она конечно для начинающего не очень простая.
Ну и конечно, мы всегда можем придумать дополнительные задачки. Один анон, например, решал задачки на XML и работу с API яндекс-карт.
>>338482
У меня как раз список задач на данный момент: мышки, рест-сервис, рг-хост.
Код мышек само собой выложу как доделаю, сейчас логика почти готова, но я всё это добро визуализировал, так что надо еще доделать связку фронтэнда и бэкэнда, плюс попробовать jquery-код оптимизировать. И код просмотреть внимательно, рефакторя по ходу дела. Тогда уже можно и на хост с гитхабом залить.
>Плохой код, лучше писать более очевидно: $a = empty($a) ? 'vocaroo' : $a;
Дак да, но тот анон явно сказал, что хочет без тернарника. Собственно поэтому и написал сразу "изъебнуться". Не как полезный пример, а как пример того, что в пыхе таки это возможно.
>В таких задачках на ООП надо просто правильно выбрать объекты, какие у них будут свойства и методы и как они взаимодействуют, и все.
Видимо я не совсем правильно понимаю значение слова "архитектура", т.к. считал, что в первую очередь она как раз это и подразумевает. Ясно теперь.
Кстати, мне кажется, что как раз для нуба вроде меня позволительно писать велосипеды, для опыта. Оглядываясь на и сверяясь с хорошими примерами, само собой. Естественно в коммерческих проектах лучше пользоваться готовыми решениями.
>>338329
Я понял, как ты предлагаешь решать это.
И да, твоё решение элегантнее, но я уже решил по-другому, и не стал переписывать всё а исправил ошибку в своём коде. Пришлось добавить несколько операторов echo в целях отладки, и теперь, надеюсь, и у меня всё правильно работает. Ты меня, ОП, не перестаёшь учить тому, как важно тщательное тестирование. Будь это не учебная задачка а мало-мальский серьезный проект, я бы без тебя выпустил его с такой-то дырой.
http://ideone.com/2Gp5Vt
>>338482
>MVC
Что такое MVC? Вики говорит Model-View-Controller
Но там как-то сложно всё. Можете в двух словах объяснить о чем конкретно речь идёт здесь? Что такое архитектура MVC?
Про круг:
http://ideone.com/gRFXaX
>>338656
http://ru.wikipedia.org/wiki/Model-View-Controller
MVC — это разделение кода на 3 части. MVC применимо не только к веб-приложениям, но и к десктопным (то есть к обычным программам типа paint), хотя оно в это случае немного разное:
Model — код, который отвечает за внутреннее представление данных. Обычно в веб-приложениях это код, работающий с БД. В графическом редакторе, например, модель — код, который хранит дерево нарисованных квадратиков, кружочков в памяти.
View — код, который отображает данные из модели. В веб-приложении view — это набор шаблонов, в графическом редакторе — это код, который рисует на экране кружочки и квадратики, записанные в модели.
С одной моделью может работать несколько view. В веб-приложении, например одно вью может выводить данные в формате HTML-страницы, другое — в формате JSON. В графическом редакторе одно вью выводит большую картинку, а другое показывает уменьшенную версию картинки для навигации.
Controller — код, который реагирует на действия пользователя, например нажатия кнопок, переход по ссылкам. Контроллер сам обычно ничего не делает, а только говорит другим что им делать (это называется тонкие контроллеры). Например, в веб-приложении, пользователь вводит текст и жмет кнопку «написать комментарий». Контроллер на сервере получает запрос, передает текст комментария в модель, она его успешно сохраняет, после чего контроллер вызывает вью и просит его вывести этот комментарий на странице.
В графическом редакторе, пользователь выделяет кружочек и жмет «Delete». Контроллер получает событие нажатой клавиши и обращается к модели, чтобы она удалила выделенный кружочек. Потом просит вью перерисовать изменившуюся область картинки (которую занимал это ткружочек).
Зачем оно нужно? Разделение на независимые компоненты делает код проще и качественнее, а без этого получается лапша.
Как разобраться в MVC? Изучить какой-нибудь MVC-фреймворк, например, Yii, или самому попробовать написать MVC-приложение, например борду.
>>338656
Алсо, в статье http://ru.wikipedia.org/wiki/Model-View-Controller есть пример кода на PHP5. Учтите, он довольно-таки отстойный, не стоит с него брать пример.
>>338655
Ну ок, твое решение конечно тоже работает, но код получился сильно запутанный и усложненный. Вот я на него смотрю, и не могу с ходу сказать, правильный он или нет (судя по результатам, правильный).
Например, я не помню, если мы удаляем текущий элемент через unset($positions[$cur]); — куда смещается указатель? На предыдущий или на следующий элемент или это поведение не определено? Эти манипуляции с указателем — очень неочевидная вещь, и я бы советовал тебе вообще избегать использование next/current/prev и подобных функций.
И это не хорошо, так как в таком коде проще допустить ошибку при правке, надо больше времени чтобы в нем разобраться (а время = деньги, если речь о работе).
Ну представь сам, тебе попадется задание разобраться в таком же запутанном коде только строк на 500.
Потому в дальнейшем старайся все-таки писать попроще.
> Будь это не учебная задачка а мало-мальский серьезный проект, я бы без тебя выпустил его с такой-то дырой.
В нормальных компаниях есть QA (тестировщики), которые должны по идее увидеть эти баги и вернуть на доработку. Но это, конечно, не везде, некоторые предпочитают сэкономить на тестировании.
>>338706
Что-то у тебя круг не круглый. Видимо там шрифт очень узкий и высокий и надо подобрать другой коэффициент (не 1.7 а больше).
> $x = round(($centerX + $hor) * 1.7);
Я думаю, надо умножать только $hor а не всю сумму.
> foreach ($screen as $value) {
> foreach ($value as $char) {
давай-ка ради улучшения кода попробуем обойтись без foreach, например с помощью implode?
>>338735
>Например, я не помню, если мы удаляем текущий элемент через unset($positions[$cur]); — куда смещается указатель? На предыдущий или на следующий элемент или это поведение не определено?
Я опытным путём установил, что смещается на следующий. Да я согласен, что код говно.
>>338728
Правильно ли я понял что так называемая концепция "ненавязчивого javaScript" отделения js кода от структуры документа - разметки html, а также отделение представления от структуры (css, когда таблицы стилей выносятся в отдеьные файлы) и php не в перемешку с html а тоже структурировано и в отдельных файликах это и есть MVC. То есть если я так делаю при разработке той же борды, то я использую эту модель?
>>338755
> Я опытным путём установил, что смещается на следующий.
Хорошо, если это описано в мануале и гарантируется. А что если это недокументированная особенность, и в следующей версии PHP, например, перепишут код работы с массивом и он начнет смещаться по другому принципу? Или он начнет смещаться в зависимости от 32- или 64-битной версии? Вот будет весело, искать причину почему на одном сервере код работает правильно, а на другом нет.
Ни в коем случае не полагайся на недокументированные особенности, которые в любой момент могут поменяться.
> Да я согласен, что код говно.
Ну не совсем, просто старайся использовать более простые и очевидные функции. Явное лучше неявного, есть такое выражение.
>>338755
> Правильно ли я понял что так называемая концепция "ненавязчивого javaScript" ... и php не в перемешку с html а тоже структурировано и в отдельных файликах это и есть MVC
Нет. MVC — это когда есть модели, вьюшки и контроллеры. А разделение страницы на разметку (HTML), оформление (CSS) и поведение (JS) — это другое. Ненавязчивый яваскрипт — вообще третье.
Идея с unobtrusive javascript была такая:
- пишем HTML/CSS страницы так, чтобы она работала без яваскрипта. Например, формы отправляются стандартным способом, ссылки работают как ссылки.
- затем, подключаем к ней внешний JS-файл. Если браузер поддерживает яваскрипт, и файл загрузился без ошибок, то этот код ставит свои обработчики на страницу, постепенно улучшая ее (progressive enhancement) и например, при вводе значений в поля формы они автоматически валидируются, отправка формы делается без перезагрузки аяксом, и так далее.
Заметь, что работоспособность страницы без JS нужна не не столько тем, у кого отключен яваскрипт. Во-первых, такая страница лучше доступна роботам и лучше индексируется. Во-вторых, если в JS-коде ошибка то сайт не перестает работать, а лишь отключаются дополнительные фичи. В-третьих, если на плохой мобильной связи JS-файл не загрузился, то сайт опять же остается работоспосбен.
Впрочем, у этого подхода есть и недостатки. Например, если сваливать в один файл JS-код для всех страниц и разделов сайта, получается та еще лапша. Также, некоторые скрипты при инициализации меняют что-то на странице (напрмер, превращают список картинок в галерею), от этого все скачет и дергается. В общем,с яваскриптом возможностей накосячить и сделать сайт хуже предостаточно.
Помогите ньюфагу. Установил PHP 5.5.6 на Apache 2.4.7. Все нормально работало пока не дошел до урока со строками. Не работает функция mbstring. Логи апачи говорят следующее:
>[:error] [pid 6032:tid 1004] [client ::1:60338] PHP Fatal error: Call to undefined function mb_strtolower()
В php.ini снял комментарий с extension=php_mbstring.dll, но легче от этого не стало.
>>338824
Апач перезапускал, mbstring в phpinfo() видно? Не тот php.ini правил?
>>338830
Перезапускал, в phpinfo() его нет. php -m выдает http://pastebin.com/qNEeuJzQ.
php.ini тот который php.ini-production. В не же правил строку extension_dir.
>>338830
Все, разобрался, таки php.ini не тот был. Спасибо за помощь.
>>338853
В следующий раз смотри phpinfo() — там выводится путь к использованному файлу с конфигом. В командной строке можно набрать php --ini .
Пхп-сенсеи, дайте ссылок на сырки имиджборд на чистых PHP + JS.
Семпай, помоги разобраться.
Читаю исходники Slim, никак не могу сообразить в методе singleton() класса Slim\Helper\Set.
Смысл и суть его работы понимаю, но вот с реализацией что-то подвис.
В частности, откуда замыкание берет переменную $c. Пробовал дампить значения переменных, но не помогло.
Код метода:
http://pastebin.com/0XqbN6Ps
Код класса:
http://pastebin.com/BK2JGnc3
А вот пример использования.
http://pastebin.com/NZ0mA9A7
Что-то я совсем в этих замыканиях заблудился.
>>339198
$this->set($key, function ($c) use ($value) {
Она передается функции в качетве аргумента.
Пройдемся по исходникам на гитхабе. Вот функция set (ищется поиском в гитхабе по слову function set):
https://github.com/codeguy/Slim/blob/ff7d7148848fa4f45712984d7b91ac3cbced586b/Slim/Helper/Set.php#L72
Она сохраняет $value (наше замыкание) в $this->data. Рядом есть функция get:
> $isInvokable = is_object($this->data[$this->normalizeKey($key)]) && method_exists($this->data[$this->normalizeKey($key)], '__invoke');
> return $isInvokable ? $this->data[$this->normalizeKey($key)]($this) : $this->data[$this->normalizeKey($key)];
Замыкания в PHP являются объектом класса Closure ( конечно у него есть магический метод __invoke про который ты можешь сам прочесть в мануале), потому авторы хитрым хаком, проверяют, является ли value замыканием или подобным объектом.
Если $value можно вызвать, они вызывают его как функцию, передавая $this в качестве аргумента (оно и присвоится в $c).
Замечу, что это нехороший хак. Чтобы проверить, можно ли вызвать переменную как функцию, лучше использовать is_callable — тогда можно будет передавать не только замыкание но и например имя функции или ссылку на метод вида array($obj, 'doDomething') или статический метод как 'class::doSomething' (подробнее тут, на английском http://www.php.net/manual/ru/language.types.callable.php ).
--
Алсо, скоро перкатимся в новый тред.
>>339199
Кстати, хочешь задачку на замыкания для развития навыков функционального программирования? (ФП — это когда функции принимают и возвращают функции). Тогда напиши функцию curry (каррирование: http://ru.wikipedia.org/wiki/Каррирование#PHP ) которая привязывает к любой функции любые аргументы. Она получает на вход функцию и от 0 до N аргументов, и возвращает новую функцию, к которой привязаны эти аргументы.
Пример:
$maxPositive = curry('max', 0); // мы привязали к функции max 0 в качестве первого аргумента.
echo $maxPositive(-2); // равносильно max(0, -2);
echo $makePositive(100, 200); // равносильно max(0, 100, 200);
Еще пример:
$leaveOnlyDigits = curry('preg_replace', '/[^0-9]+/', '');
// мы сделали функцию, убирающую из строки все кроме цифр
echo $leaveOnlyDigits('100-200-300'); // равносильно preg_replace('/[^0-9]+/', '', '100-200-300'); выведет 100200300
Еще пример:
$trimArray = curry('array_map', 'trim'); // функция делающая trim каждому элементу в массиве
$r = $trimArray(array(' a ', ' b', ' cc '));
var_dump($r);
>>339202
Если ты сделал curry, то попробуй сделать еще пару улучшений. Во-первых, наша curry позволяет привязывать только первые N аргументов функции. А что, если нам нужна такая функция:
strtr({не привязанный аргумент}, {привязанный})
Очевидно, надо улучшить функцию curry. Добавь в нее возможность указания непривязанных аргументов:
$myStrtr = curry('strtr', PASS, array('a' => 'A', 'b' => 'B'));
echo $myStrtr('abcd'); // равносильно strtr('abcd', array('a' => 'A', 'b' => 'B'));
Если ты и это легко сделал, сделай еще функцию compose. Она берет 2 или больше функции на вход и делает из них составную функцию:
$fn = compose($f1, $f2, $f3);
Результат которой равносилен вызову этих функций по очереди:
$fn = $f1($f2($f3(.....)));
Пример. Мы хотим собрать функцию, которая берет строку, разеделеную запятыми, разбивает на части, делает trim() всем элементам массива, и потом удаляет из него пустые элементы. Поколдуем:
// удаляет путсые элементы из массива
$removeEmpty = curry('array_filter', PASS, function ($s) { return $s !== ''; });
// обрезает строки в массиве
$trimArray = curry('array_map', 'trim');
// разбивает на части
$splitString = curry('explode', "\n");
// все вместе
$parse = compose($removeEmpty, $trimArray, $spplitString);
// тест
$result = $parse(" a1 , a2 , ,,,, a3");
var_dump($result); // получается array('a1', 'a2', 'a3')
Если тебе потом захочется более глубоко изучитьт ФП, почитай про Хаскелл.
>>339200
От жеж, код метода get() тоже просматривал, а на передачу аргумента в конце $this->data[$this->normalizeKey($key)]($this) не обратил внимание. Спасибо, теперь понял.
Нет бы этот $c назвать $that или еще как-нибудь попонятней.
Алсоу, вроде как функции принимающие и передающие (и создающиеся в рантайме) это просто ф-ции первого класса, а ФП - это уже пучина отсутствия стейта и императивных команд и прочих извращений, не? Или как раз ф-ции как объекты первого класса - отличительная черта ФП?
Задачки попозже попробую решить. Хаскель как-то не прельщает, но элементы ФП интересны, скорее не для PHP даже, а в контексте JS. Backbone.js, Underscore.js, вот это вот всё.
Кстати, раз уж за ФП разговор прошел. Ты SICP случаем не читал? Как считаешь, стоит оно того? Сам знаешь, какая у этой книги слава, мол, дарует интеллектуальное просветление, жизнь никогда не будет прежней, etc.
Алсоу_2, а чего ты от трипкода избавился?
>>339214
> Нет бы этот $c назвать $that или еще как-нибудь попонятней.
Передается вроде бы туда $slim->container, логично его назвать $container, а $c — это сокращение от него.
> Алсоу_2, а чего ты от трипкода избавился?
А он при перезапуске браузера очищается же и надо его заново вводить. Не то чтобы я так часто перезапускаю браузер, но вот недавно перезагрузить Windows пришлось, трипкод очистился.
> Алсоу, вроде как функции принимающие и передающие (и создающиеся в рантайме) это просто ф-ции первого класса, а ФП - это уже пучина отсутствия стейта и императивных команд и прочих извращений, не? Или как раз ф-ции как объекты первого класса - отличительная черта ФП?
Упс, тут я понял, что сам не особо разбираюсь в функциональщине. Но в примерах кода в задании — переменных и императивных команд вроде и нету, только функции (ок, мы храним их в переменных но только потому, что без них будет нечитабельно).
> Ты SICP случаем не читал? Как считаешь, стоит оно того?
Нет. Возможно, и стоит, судя по описанию в вики там есть интересные вещи.
http://ideone.com/4DKBhk
БЛДЖАД, ДА ЧТО НЕ ТАК С ЭТОЙ СТРОКОЙ?! Опчик, выручай.
>>339286
Поясню, выдаёт синтаксическую ошибку на 177 строке.
>>339289
Упс, похоже ты уже все исправил. Ну молодец.
Ничего я не исправил, по-прежнему не работает же.
>>339319
Тогда ссылку покажи. По ссылке http://ideone.com/4DKBhk я не вижу синтаксических ошибок. Там есть только
PHP Notice: Undefined index: nov in /home/schbsP/prog.php on line 184
А это просто ошибка что в массиве в строке 184 нет нужного ключа, а ты пытаешьс его прочесть. Натыкай var_dump() и посмотри что в переменных.
>>339321
Фух, разобрался!
http://ideone.com/I4njoh
>>339343
По алгоритмам советую начать с Википедии. Там есть список алогоритмов.: http://ru.wikipedia.org/wiki/Поиск_пути Один анон например Дийкстрой делал.
Хочу возмутиться. MySQL, как известно, позволяет указать при создании таблицы ограничение для колонки (CHECK(....)) но оно в лучших традициях MySQL не работает: http://stackoverflow.com/a/14247690
Я точно помню, что несколько лет она это тоже не умела. Прошли годы, и что? Так до сих пор и не умеет. Неужели так трудно сделать эту фичу? неужели нужны какие-то сверхспособности, чтобы при вставке значения проверить его функцией?
А так, любой клоун может вставить в базу что угодно и никто ему не помешает.
Алсо, скоро перекат.
>>339348
Опять поторопился, половина маршрутов не работала. Ну теперь-то точно всё. Так я тоже по алгоритму Дейкстры делал.
Там такая-статья про него хорошая и понятная на Википедии.
http://ideone.com/PfQWQA - теперь, по-моему, всё работает.
Оп, а есть задачки с MySQL поучиться работать чтобы?
>>339368
По MySQL: тренироваться можно на http://sqlfiddle.com/ или скачав и установив MySQL. Для начала запросы лучше писать руками, как освоишься, можешь переходить на программы с графическим интерфейсом или adminer.php
На sqlfiddle слева фигачишь команды создания таблиц и вводишь начальные данные, делаешь build schema, потом справа можно фигачить запросы.
Из теории есть большой учебник по SQL http://www.opennet.ru/docs/RUS/rusql/ , есть немного устаревший перевод мануала MySQL (SQL — это язык, а MySQL — это база данных, которая имеет свои нестандартные особенности) http://phpclub.ru/mysql/doc/
Насчет задач ... ну даже не знаю, давай начнем с чего-нибудь простого:
Есть какой-нибудь сайт, на нем есть пользователи (у каждого свой уникальный id, и например имя и логично что нужна таблица для их хранения), и эти пользователи могут ставить друг друг лайки (соответсвенно, это тоже надо где-то хранить). Один пользователь может лайкнуть другого только один раз конечно (это должно контролироваться на уровне БД). Сделай запрос, который выведет такую таблицу:
- ид пользователя
- имя
- лайков получено
- лайков поставлено
- взаимных лайков
Сложно? Ну ок, давай начнем с более простой задачи: просто выведи 5 самых популярных пользователей.
>>339374
В качестве решения надо: дать SQL-запросы, который создают таблицы и набивают их данными и SQL-запрос который эти данные выбирает в нужном виде. Ну или просто дать ссылку на sqlfiddle с решением.
>>339374
Хотя я тут подумал, ты же офигеешь писать такой запрос. Давай для начала просто сделай 3 отдельных таблицы, в первой сколько каждый юзер получил лайков, во второй, сколько поставил, в третьей сколько взаимных.
По программе поиска пути: я потестировал, вроде считает правильно, но нехорошо что весь код свален в одну кучу: расчет пути и вывод данных связаны и если например завтра тебе понадобится выводить результат в каком-то другом виде, надо будет это распутывать. Лучше делать код отдельными функциями: одна функция ищет лучший путь и возвращает например список точек, вторая этот список выводит в нужном виде.
Добрый день. В этом треде мы изучаем основы языка PHP (и немного HTML) и решаем простые задачки. Зачем? Кому-то интересно, что такое программирование, или как делают сайты, или просто хочется отвлечься от безделья и поработать мозгами. Полезно же.
Для удобства читателей архивы уроков по PHP выложены по адресу http://archive-ipq-co.narod.ru Если ты ньюфаг, просто решай задачки оттуда, они там реально простые, и пости сюда ссылки на решения, мы посмотрим и скажем, правильно или нет. Если не совсем ньюфаг, напиши, что ты знаешь, что нет, я дам тебе какую-нибудь задачку посложнее.
Требуемые знания: умение включить компьютер и пользоваться браузером. Если ты читаешь этот текст, оно у тебя скорее всего есть. Устанавливать и скачивать пока что ничего не требуется, разве что редактор кода вроде Notepad++ или Sublime (необязательно).
Правила: ведем себя воспитанно, помогаем новичкам, постим ссылки на решения задачек.
Предыдущий тред: >>327422
ОП, как всегда, помогает и дает советы, отвечает на самые нубские и простые вопросы. У ОПа есть почта, так что даже если он не появляется в треде уже неделю, вы всегда можете написать ему что-то хорошее.
Оформляй код правильно!!! например пропусти через phpformatter.com
Сайт опять упал!!!!! Не паникуй, а открой http://rghost.net/45000175
Тред не открывается!!! Можешь спросить совет или проверить решение, написав письмо ОПу (адрес на сайте)
Где архивы старых тредов? Известно, где, на mediafire: http://www.mediafire.com/?vz0z5134irhn2zl (треды 1-10, 160 Мб) http://www.mediafire.com/?3zxb19z9j2q5gf2 (11-19, 74 Мб) и на дропбоксе: https://www.dropbox.com/sh/4sb69jrx9qwrpcw/-nY5ia__VC (ок, он иногда не работает)
Не понимаешь, как дальше решать задачу? Запости свой код и напиши, где затык, что непонятно.
Решил сложную задачу? Покажи решение, может оно не такое уж и правильное.
Куда постить код Удобнее всего на ideone. Пости ссылку на ideone, код копипастить не надо. Еще, говорят, модно постить на instacode. HTML, CSS и JS постят на jsbin.com
Как привести код в аккуратный вид? Закачай его на phpformatter.com, робот его выровняет как надо.
Решил задачу, но ничего не понял? Попроси еще пару для закрепления знаний.
А HTML, CSS у вас изучают Ну, у нас есть несколько простых задач на верстку. На сайте в разделе «Учим сами».
В общем, хватит разговоров, давайте начинать уже!