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

Клуб любителей изучать PHP #13

 !xnn2uE3AU. Срд 06 Ноя 2013 23:20:52  #1 №333445 

Добрый день. В этом треде мы изучаем основы языка 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 у вас изучают Ну, у нас есть несколько простых задач на верстку. На сайте в разделе «Учим сами».

В общем, хватит разговоров, давайте начинать уже!

!xnn2uE3AU. Срд 06 Ноя 2013 23:25:53  #2 №333446 

... Но прежде чем начинать! Код надо писать не как попало, а аккуратно и красиво. Почему? Потому, что на неакуратно написанный код не хочется даже смотреть.

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


В общем, пиши как на картинке, и проблем не будет.
!xnn2uE3AU. Срд 06 Ноя 2013 23:38:53  #3 №333452 

Как установить PHP под Windows? Картинка слева.

Как установить Апач самому? Паста → https://gist.github.com/anonymous/946f4f1830be3955fe17
Как начать пользоваться командной строкой? Паста → https://gist.github.com/anonymous/2dfa134fe20d9cf91bbe

!xnn2uE3AU. Срд 06 Ноя 2013 23:41:52  #4 №333454 

Как установить PHP, продолжение.

Аноним Чтв 07 Ноя 2013 00:01:05  #5 №333463 

>>333454
Ох уж эта убогая cmd.exe.

Аноним Чтв 07 Ноя 2013 03:27:35  #6 №333488 

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

Аноним Чтв 07 Ноя 2013 03:35:54  #7 №333490 

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

!xnn2uE3AU. Чтв 07 Ноя 2013 10:03:56  #8 №333513 

>>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; // все ок
}


Если полей много, то вместо копипасты можно использовать например цикл. Ну а вообще, в фремйворках есть специальные способы для описания форм, чтобы не надо было такие проверки писать руками.
!xnn2uE3AU. Чтв 07 Ноя 2013 10:13:35  #9 №333515 

>>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',
.....
);


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

Как написать функцию, которая будет на основании этого набора правил получать и проверять поля формы, я думаю, ты можешь догадаться и сам.
Аноним Чтв 07 Ноя 2013 10:24:57  #10 №333517 

>>333515
в ООП принципиально новый подход будет к проверке разве?

!xnn2uE3AU. Чтв 07 Ноя 2013 11:17:01  #11 №333522 

>>333517

Ну в Zend_Framework например форма сделана объектом, валидаторы для полей тоже отдельными объектами. Не то что принципиально новый подход, но немного по-другому. В фреймворках обычно не надо писать код проверки руками, а ты просто описываешь правила для полей (а код проверки уже встроен в фреймворк). И не только проверки, но и например, код для вывода формы тоже уже есть, он создает HTML-код формы по описанным тобой полям.

Аноним Чтв 07 Ноя 2013 12:04:50  #12 №333526 

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

Аноним Чтв 07 Ноя 2013 12:19:41  #13 №333528 

ОП, помоги пожалуйста с задачкой. Я даже алгоритма не смог придумать который сможет реализовать все это, а сделать нужно. Суть такова: есть текстовый файлик, куда написаны теги html. Скрипт должен прочесть этот файлик ивывести OK если порядок тегов правильный и нет ошибок в них, если же где-то есть ошибка, то вывести номер строки в которой она допущена. Не нужно проверять названия тегов и прочее, нужно лишь проверить является ли это тегом (открывающий и закрывающий уголок, возможно какие-то атрибуты), и если является проверить, имеется ли закрывающий тег. Открывающий тег может быть на одной строке, а закрывающий на другой. Условие таково, что ошибка будет только в том случае, если тег разделен построчно или после <body> идет сразу </html>, без закрытия <body>. Пикрелейтед задание в целом. Как его сделать вообще не понимаю. Подскажи пожалуйста.

Аноним Чтв 07 Ноя 2013 12:23:33  #14 №333532 

>>333513>>333515
Меня интересует скорее логика таких проверок(на isset и empty), для тех форм которые заведомо "не опасные", что ли.
Например, есть форма редактирования статьи в админке, которая появляется при клике на кнопку edit. В этой форме можно поправить текст и заголовок, а остальные данные - id, автор, время написания - передаются в скрытых полях. Текст и заголовок не могут быть пустыми, ок, но зачем кому-то с разрешенным доступом в админку пытаться вписать в базу пустые значения id, автора и времени? Угробить базу из админки можно и проще же. Другой пример - есть форма фильтрации товаров, например, машин. На ней три селекта - новая/подержанная, иномарка/отечественная и красная/синяя. Пустые значения там никак не выберешь, в базу ничего не пишется, по идее достаточно mysql_real_escape_string от инъекции и все. Тем не менее лектор видеокурсов проверяет абсолютно все на свете на isset и empty.
Насчет нечитаемой лапши он оговаривается что это для экономии времени, в отдельном уроке показывает как правильно делать, примерно как у тебя.

Аноним Чтв 07 Ноя 2013 12:51:05  #15 №333536 

>>333148

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

Спасибо, доброе слово и макаке приятно :3
Хотя особо радоваться нечему - я уже достаточно долго говнокодингом занимаюсь, правда, пугающе нерегулярно. Будь на моём месте кто-нибудь более целеустремленный, давно бы уже к успеху пришел.

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

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



Код поправил, замечания принял к сведению.
Хитрый трюк с транспозицией (так вроде называется?) матрицы через array_map() очень крут.

Кстати. Встретил очень занимательно написанную серию статей про функциональные возможности PHP, может кому интересно будет: http://www.recessframework.org/page/functional-php-anonymous-functions-lambdas-closures
Еще спросить хотел, есть ли какие-нибудь реальные применения ф-ции array_reduce для рядового уеб-кодерка?

!xnn2uE3AU. Чтв 07 Ноя 2013 12:51:54  #16 №333538 

>>333532

> Меня интересует скорее логика таких проверок(на isset и empty), для тех форм которые заведомо "не опасные", что ли.
Если это админка, которой пользуешься только ты, это другое дело, ты можешь вообще ничего не проверять. Но ведь кроме злонамеренных изменений, есть еще баги, например из-за бага в форму в невидимое поле подставляется кривое или пустое значение. Если не делать проверок, то ты сам того не заметив, поломаешь данные в базе.

> Тем не менее лектор видеокурсов проверяет абсолютно все на свете на isset и empty.
Это чтобы варнинги не сыпались если параметр не передан.

Аноним Чтв 07 Ноя 2013 12:52:45  #17 №333539 

>>333528

!xnn2uE3AU. Чтв 07 Ноя 2013 12:53:40  #18 №333540 

>>333528

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

!xnn2uE3AU. Чтв 07 Ноя 2013 12:58:02  #19 №333544 

>>333539

Ты вопрос ОПа прочел? Где там слово регулярки? Алсо, автор ответа не прав, я не раз парсил (X)HTML регулярками и все работало, и проблем не было. Алсо, автор ответа похож на рубиребенка. Как я это угадал? По последней строчке:

> Have you tried XML parser instead

Аноним Чтв 07 Ноя 2013 12:59:34  #20 №333547 

>>333538
>Это чтобы варнинги не сыпались если параметр не передан.
А вот эта конструкция как тебе? Дурной тон или ок?

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

$name = @$_POST['name'] or $name = 'имярек';

Аноним Чтв 07 Ноя 2013 13:07:16  #21 №333550 

>>333544
Хэй-хэй, это слегка рилейтед шуточка же. Смешная как по мне.

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

Алсо, в чем проблема использовать XML парсер в PHP? Тот же DOMDocument.

!xnn2uE3AU. Чтв 07 Ноя 2013 13:19:52  #22 №333557 

>>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) и в других языках.

!xnn2uE3AU. Чтв 07 Ноя 2013 13:25:07  #23 №333559 

>>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-ом.

В общем, надо смотреть по ситуации.

!xnn2uE3AU. Чтв 07 Ноя 2013 13:26:46  #24 №333560 

>>333547

Дурной. @ = быдлокод

Если тебе лень писать каждый раз isset, в чем проблема поместить isset в функцию и использовать ее? Например: $name = ge('name');



Аноним Чтв 07 Ноя 2013 13:46:34  #25 №333565 

>>333560
>в чем проблема поместить isset в функцию и использовать ее?

Гм, логично.

>@ = быдлокод
Можешь развернуть? Почему конкретно в этом примере это плохо, кроме того, что @ - плохо и не модно само по себе? Я просто не понимаю, какие тут подводные камни и встречал эту конструкцию на stack overflow, там вроде никто не плевался.

!xnn2uE3AU. Чтв 07 Ноя 2013 13:52:35  #26 №333567 

>>333536

Вот еще интересная вещь: итераторы в PHP. Вот пример, какие штуки можно вытворять с рекурсивным массивом: http://ideone.com/hk9bfN

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

!xnn2uE3AU. Чтв 07 Ноя 2013 13:57:42  #27 №333569 

>>333565

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

Пример: $x = @$array['x']; предполагается что @ нужна для обхода случаев когда в массиве нет элемента. Но (внезапно) она скроет и ошибку, когда $array не существует или не является массивом. Используя @ мы делаем код хуже.У нее столько подводных камней, что проще от нее отказаться.

!xnn2uE3AU. Чтв 07 Ноя 2013 14:10:07  #28 №333572 

>>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/ )

Аноним Чтв 07 Ноя 2013 14:17:36  #29 №333574 

>>333572
>PDO

!xnn2uE3AU. Чтв 07 Ноя 2013 14:24:44  #30 №333577 

Анон как-то спрашивал, как прибавлять даты в PHP. Нашел новый способ, с использованием класса DateTime: http://getjump.github.io/ru-php-the-right-way/#Дата_и_Время

Аноним Чтв 07 Ноя 2013 16:26:11  #31 №333615 

>>332256

Ох, что то тяжко идёт освоение Yii. Читаю и выполняю "Создание блога с использованием Yii". http://yiiframework.ru/doc/blog/ru/start.overview
Но плохо понимаю, то что я делаю. Такое ощущение, что учу как-то неправильно.
Сколько времени уходит на то чтоб научиться делать в yii что-нибудь простое, но самостоятельно?

Аноним Чтв 07 Ноя 2013 16:33:11  #32 №333618 

>>333615
Гыйи нужен для того, чтобы не увели заказ на сторону.
Переусложнённость, как правило никому не нужная - от этого.

Web, что поделать.

Аноним Чтв 07 Ноя 2013 19:21:48  #33 №333621 

Аноны. Не могу додуматься. Маны перечитал пару раз и все что понял это вот:
" /^8[-|(]([0-9]{3})[)|-|(][0-9]{3}[)|-|(][0-9]{4}/ " рег.выражение, которое проверяет правильность введеного номера. [)|-|(] - значит что в этом месте может стоять как ), так и -, такт и ( или же все три сразу, верно?
Задание с archive-ipq-co.narod.ru.

Аноним Птн 08 Ноя 2013 15:58:29  #34 №333631 

Есть необходимость хранить в базе HTML-код статьи, то есть текст вместе с тегами, например
<h1>Заголовок статьи</h1>
<p>Текст абзаца<a href='#'>Ссылка</a></p>
Проблема заключается вот в чем - когда делаю сокращенный вывод, скажем, первые 100 символов и ссылку "... read more" может получиться так, что substr($text,0,100) разорвет какой-то тег, например <a href='' class=''> где-нибудь посреди атрибутов и тогда вообще весь остальной текст страницы окажется текстом этой ссылки.
Должна же быть изящная функция для этого без лишней ебатни?

Аноним Птн 08 Ноя 2013 16:30:55  #35 №333640 

>>333615
Узнаю себя в твоём посте. Когда читал - думал ебанусь со всего этого. Ну никак не мог вкурить что там и как. Проблема в том, что документация написана в таком ключе, что типо "вот то то мы делаем так и так (но можно и так, и вот так тоже можно)" но оно не даёт СИСТЕМНОГО ПОНИМАНИЯ. Моя тебе рекомендация - запили какой нибудь проектик на нём. Попутно пользуй гугл и класс референс. Я например сейчас просто кончаю радугой с ЙИИ и думаю все свои простенькие быдло-проэктики на него перетащить. Причина проста - разработка тех самых проектов с нуля на фреймворке займёт на много меньше времени, чем их поддержание в текущем их состоянии.
> Сколько времени уходит на то чтоб научиться делать в yii что-нибудь простое, но самостоятельно?
Прошло примерно 20 рабочих часов, пока на меня снизошло тотальное понимание. Сайчас чувствую себя богом веб-разработки.

Алсо, Аноны, стоит ли упарывать симфони или зенд? И какие профиты можно с них получить по сравнении с ЙИИ?

Аноним Птн 08 Ноя 2013 17:27:57  #36 №333649 

>>333631
Вопрос не актуальный, в моем случае приемлемо substr(strip_tags($text),0,100) но вообще, погуглив удивлен тем что задача легкой обрезки html-кода далеко не тривиальная.

!xnn2uE3AU. Птн 08 Ноя 2013 20:09:38  #37 №333697 

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

>>333618

Ты пишешь бред.

>>333615

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

!xnn2uE3AU. Птн 08 Ноя 2013 20:14:59  #38 №333700 

>>333621

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

[)|-|(] значит что в этом месте может быть один из символов ) | - или ( но не все 3 сразу
[)|-|(]+ — значит что тут может быть от 1 до бесконечности любых из этих символов в любом порядке
[)|-|(]{3} — значит что тут должно быть любые 3 символа из указанных в любом порядке

Алсо, внутри квадратных скобок большинство символов не имеет специального значения. | ? * ( ) { } — все эти символы просто обозначают сами себя. Но вот минус внутри квадратных скобок значит «от и до», например 0-9 — от 0 до 9, a-z от a до z. И если ты хочешь написать просто минус, то ставишь его либо в конец [0-9./+-] либо добавляешь бекслеши [0-9\\-./+]

!xnn2uE3AU. Птн 08 Ноя 2013 20:22:15  #39 №333701 

>>333640

> Алсо, Аноны, стоит ли упарывать симфони или зенд?
Если ты их поймешь, то почуствуешь себя богом архитектуры в сравнении с теми, кто использует примитивные фреймворки вроде Yii. Учти, что там есть ZF1 и ZF2 и Symfony 1 / 2 и они сильно различаются. 2-е версии конечно круче.

> но оно не даёт СИСТЕМНОГО ПОНИМАНИЯ
Да, есть такое. Люди, которые привыкли писать кривые скриптики, где все в кучу, не сразу понимают преимущества правильной архитектуры и разделения кода на MVC, виджеты, валидаторы и что там еще есть.

>>333631

> Должна же быть изящная функция для этого
О, можно будет сделать из этого задачку и давать анонам.

Аноним Птн 08 Ноя 2013 20:55:04  #40 №333705 

Привет братве, привет доброкунчик. Такой вопрос: мне нужно чтобы некоторый скрипт постоянно висел в памяти, и раз в N минут делал кое-какие проверки. Я могу это просто набылокодить в своем коде, но дело в том, что задача для приложения, в котором участвую неск-ко человек. Разработка на Yii. Поэтому все должно быть максимально прилично. Там еще куча всяких условий, но мне как это принципиально делается, в концепции MVC и Yii. Может у кого есть опыт?

!xnn2uE3AU. Птн 08 Ноя 2013 21:01:00  #41 №333711 

>>333705

Если раз в N минут, используй крон, который будет вызывать твой cli-скрипт (cli = для командной строки) раз в N минут. Это традиционный способ.

Для создания cli-скриптов в Yii есть готовые средства: http://www.yiiframework.com/doc/guide/1.1/en/topics.console

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

Аноним Птн 08 Ноя 2013 21:02:03  #42 №333712 

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

Я так понял, для начала сделать это без Yii? Потому что на данном этапе я пока пытаюсь понять что к чему там.

Аноним Птн 08 Ноя 2013 21:14:44  #43 №333716 

>>333711
Мне нужно чтобы этот скрипт запускался только если определенный тип пользователей зашел в систему. Пользователи разделены по ролям. Если заходит нужный пользователь, то этот скрипт запускается, и запускает крон. Как-то так. Ладно, спасибо вобщем за ссылку. Кстати, я в прошлом треде спрашивал про грид и отдельную форму поиска для него - с большим трудом я это сделал!

!xnn2uE3AU. Птн 08 Ноя 2013 21:15:58  #44 №333720 

>>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

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

Аноним Птн 08 Ноя 2013 21:16:38  #45 №333722 

>>333716
Кстати
>>только если определенный тип пользователей зашел в систему
это как раз не сложно. Я что-то не додумал

!xnn2uE3AU. Птн 08 Ноя 2013 21:26:58  #46 №333728 

>>333716

> то этот скрипт запускается, и запускает крон
Не, ты не можешь запустить крон.

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

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

Можно запускать скрипт отдельным фоновым процессом из PHP, через команду вроде exec('nohup php myscript.php & ') — минус такого подхода, что ты никак не контролируешь что происходит дальше и не получаешь обратной связи. Ну зато это несложно. Может тебе подойдет такой вариант.

Еще это реализуют через очередь задач: когда нам надо что-то сделать, мы добавляем задание в очередь. Специальный демон или крон-скрипт постоянно проверяет очередь, берет из нее задачи и запускает воркеров для выполнения, следит за ними, пишет логи. Это можно даже делать в несколько потоков, такие системы уже есть готовые, например http://gearman.org/

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

Аноним Птн 08 Ноя 2013 22:59:33  #47 №333757 

>>333567
>итераторы в PHP
А yield и генераторы ещё пока в php не завезли?

!xnn2uE3AU. Птн 08 Ноя 2013 23:18:49  #48 №333763 

>>333757

Завезли, в 5.5: http://php.net/manual/ru/language.generators.overview.php

Аноним Птн 08 Ноя 2013 23:20:30  #49 №333764 

Как мне в RegularExpression искать слова от 4 букв на любых языках без цифр?

!!8VDVWZyN Птн 08 Ноя 2013 23:30:36  #50 №333769 

http://dumpz.org/722942/

Оп, не слишком ли это быдлокодно?
У меня весь код в таком стиле.

Всё ещё тот кун, который не доделал обменник на Slim Framework.

Аноним Птн 08 Ноя 2013 23:31:56  #51 №333771 

>>333764
\w{4}\w*

Аноним Птн 08 Ноя 2013 23:41:20  #52 №333773 

>>333728
расскажи как обернуть код в транзакции?

!xnn2uE3AU. Птн 08 Ноя 2013 23:50:40  #53 №333775 

>>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

Аноним Птн 08 Ноя 2013 23:51:58  #54 №333776 

>>333775
2ch же.

!xnn2uE3AU. Птн 08 Ноя 2013 23:56:42  #55 №333778 

>>333773

Теория про уровни изоляции транзакций: http://habrahabr.ru/post/135217/

Еще, кстати, транзакции в некоторых случаях ускоряют вставку записей в MySQL. Например, вставить 10 записей одной транзакцией обычно быстрее, чем 10 отдельными запросами (по сути в этом случае каждый запрос идет как одна транзакция). Почему? Потому, что при записи транзакции MySQL сбрасывает данные на диск и ждет ответа от ОС, что все сбросилось, чтобы убедиться что данные надежно сохранены (а это не очень быстро), и ждать один раз быстрее, чем сбросить данные 10 раз подряд и 10 раз ждать.

Аноним Птн 08 Ноя 2013 23:59:11  #56 №333779 

>>333775
Пароль: 2ch

!xnn2uE3AU. Суб 09 Ноя 2013 00:08:55  #57 №333782 

>>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()) { ... } и твой код будет лучше.

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

В общем, есть что улучшать.

!xnn2uE3AU. Суб 09 Ноя 2013 00:14:52  #58 №333784 

>>333769

> $search_results_
Вот это особенно плохо. Мне пришлось вглядываться в экран, чтобы увидеть что это не у меня глюки, а действительно 2 разных переменных. Не делай так. А переименуй:

$search_results → $search_statement или $search_stmt
$search_results_ → $search_results или $files




!xnn2uE3AU. Суб 09 Ноя 2013 00:16:31  #59 №333785 

>>333769

> while($a = $search_results->fetch()){
Открой для себя fetchAll: http://www.php.net/manual/ru/pdostatement.fetchall.php

Аноним Суб 09 Ноя 2013 00:20:56  #60 №333788 

>>333775 >>333778
спасибо, знал что такое транзакции и для чего но не делал их на php Mysql никогда

Аноним Суб 09 Ноя 2013 00:27:21  #61 №333790 

>>333778
хммм а кто-нибудь знает подводные камни? почему не панацея в использование?

!xnn2uE3AU. Суб 09 Ноя 2013 00:43:03  #62 №333794 

>>333790

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

Аноним Суб 09 Ноя 2013 01:06:09  #63 №333800 

ОП-кун, вот очередная задачка, на поиск пути. Жду комментов.
Вместо того, чтобы городить велосипеды реализовал алгоритм Дейкстры. Единственный косяк, если не считать потенциально неэффективных кусков кода, - то, что не обработан случай, когда из А в Б в принципе нельзя добраться.

Итераторы оно круто, конечно, на заметку возьму, но пока плотно изучать не буду.

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

!xnn2uE3AU. Суб 09 Ноя 2013 01:24:20  #64 №333805 

>>333800

Задачку-то не приложил.

Аноним Суб 09 Ноя 2013 09:23:16  #65 №333862 

>>333805
http://viper-7.com/6vHrF4

Аноним Суб 09 Ноя 2013 11:32:49  #66 №333887 

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

Аноним Суб 09 Ноя 2013 12:18:26  #67 №333893 

>>333887
<?php echo htmlspecialchars($yoba); ?>

Аноним Суб 09 Ноя 2013 14:04:05  #68 №333913 

>>333887
<?=$yoba;?>
>>333893
обрабатывать данные в бекенде нужно.

Аноним Суб 09 Ноя 2013 14:10:42  #69 №333916 

>>333913
согласен
а так нормально
что есть echo в самом html коде?

!xnn2uE3AU. Суб 09 Ноя 2013 18:16:58  #70 №333939 

>>333913

> обрабатывать данные в бекенде нужно.
Это как? По моему, либо я тебя не понял, либо ты ошибаешься. htmlspecialchars — это не обработка данных, а перевод просто текста в HTML.

Правильно писать именно <?= htmlspecialchars($yoba); ?> чтобы любые символы, в том числе < > и & в $yoba выводились корректно и в соответствие с правилами HTML.

Плюс, как ты «обработаешь в бекенде» обращение к методам модели, например: <?= htmlspecialchars($project->getTitle()) ?>

Кстати, умные шаблонизаторы, (например Google Closure Templates или XSLT) делают htmlspecialchars сами.

Аноним Суб 09 Ноя 2013 18:20:29  #71 №333940 

Есть index.php, в который путем include подключаются остальные странички. Есть javascript-функция которая, например, запрещает ввод любых символов кроме цифр в строку, т.е. обычная вспомогательная функция. Используется она, допустим, на двух-трех из двадцати подключаемых страницах. И таких функций очень много. Как правильнее - вставить их все один раз в index.php или копировать по тем страницам где они реально нужны? В первом случае засираем индексный файл кодом, который может и не понадобится, во втором дублируем одни и те же куски по нескольким страницам.

!xnn2uE3AU. Суб 09 Ноя 2013 18:27:57  #72 №333943 

>>333940

Копипастить — плохо.

Можно к каждой странице подключать 2 JS-файла: global.js — функции, которые нужны везде или почти везде, page-x.js — только на странице x. Эта твоя функция пойдет в global, а вызываться будет только там, где нужна.

Аноним Суб 09 Ноя 2013 18:36:49  #73 №333948 

Макаканы, помогите построить базу, с которой можно пилить сайты с нуля?
Для html и css - это boilerplate. Обнуление стилей классная штука, чтобы все элементы на странице выглядели во всех браузерах максимально похожи. Алсо там есть шаблонный .htaccess для Апача.
Далее: для JS нам пригодится html-shiv, чтобы IE не тупил с новыми HTML5-тэгами и jQuery.
Для mysql ничего не нужно.
А теперь самое главное: на чем строить php-скрипты? Около месяца разбирался с Zend 2. Это просто охренеть, какая монструозная и комплексная штука. Согласен, там есть модули на все случаи жизни, но сама повседневная разработка очень уж утомляет. Если я на чистом PHP за 15 минут склепаю форму и ее валидацию на стороне сервера, то для такой тривиальной задачи в Zend'e мне придется поебаться в 2 раза дольше. Там и злоебучая маршрутизация и сущности базы данных с гидратацией, это слишком для простого новостного сайта, скажем.
Но если писать на голом PHP, то я становлюсь неуверен в безопасноти. Постоянно опасаюсь SQL-инъекций. А в Zende все сделает за тебя класс взаимодействия с БД.

Как же быть, анон?

!xnn2uE3AU. Суб 09 Ноя 2013 18:40:33  #74 №333950 

>>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.

!xnn2uE3AU. Суб 09 Ноя 2013 18:52:00  #75 №333955 

>>333948

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

reset давно устарел, это даже на западе наконец-то поняли, и в том же bootstrap используют не reset, а normalize.css (ну а мне было очевидно с самого начала, что reset — это типичный быдлоскрипт для индусов, которым плевать на качество). Не советую его использовать, советую изучать CSS и знать особенности браузеров.

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

> Если я на чистом PHP за 15 минут склепаю форму и ее валидацию на стороне сервера
C подстановкой сообщений около нужных полей, сохранением значений, CSRF токеном и прочими плюшками? Да ну, сомневаюсь.

> помогите построить базу, с которой можно пилить сайты с нуля?
Фреймворки же, Yii например или ZF (но он сложнее) + расширения и плагины к ним + что-нибудь готовое для админки. Zend 2, конечно, не самая простая штука.

!xnn2uE3AU. Суб 09 Ноя 2013 18:53:25  #76 №333956 

>>333948

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

reset давно устарел, это даже на западе наконец-то поняли, и в том же bootstrap используют не reset, а normalize.css (ну а мне было очевидно с самого начала, что reset — это типичный быдлоскрипт для индусов, которым плевать на качество). Не советую его использовать, советую изучать CSS и знать особенности браузеров.

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

> Если я на чистом PHP за 15 минут склепаю форму и ее валидацию на стороне сервера
C подстановкой сообщений около нужных полей, сохранением значений, CSRF токеном и прочими плюшками? Да ну, сомневаюсь.

> помогите построить базу, с которой можно пилить сайты с нуля?
Фреймворки же, Yii например или ZF (но он сложнее) + расширения и плагины к ним + что-нибудь готовое для админки. Zend 2, конечно, не самая простая штука.

Алсо, советую лучше заниматься чем-то одним, например, бекендом на PHP, а верстку свалить на кого-нибудь другого, зачем тебе сидеть пиксели выравнивать, лепить костыли для ИЕ и скрипты отлаживать, когда ты можешь заниматься более высокоуровневыми вещами?

Аноним Суб 09 Ноя 2013 18:58:29  #77 №333963 

>>333955
А чем годен Yii? Самое основное, что мне нужно, это класс для работы с БД, зародыш админки и зародыш системы залогинивания.

!xnn2uE3AU. Суб 09 Ноя 2013 19:05:42  #78 №333965 

>>333963

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

Аноним Суб 09 Ноя 2013 19:11:42  #79 №333970 

>>333965
Пока читаю take a tour на офф. сайте спрошу такую вещь: планирую впервые в жизни пилить сайт, через который идут интернет платежи. Насколько сложно прикрутить к нему всякие Киви, Вебмани, Яндексы, PayPal'ы?

Аноним Суб 09 Ноя 2013 19:19:49  #80 №333976 

Скриптаны, хочу запилить свой сайт, чтобы приносил доход хотя бы 100$ в месяц. В какую тематику идти?
Алсо пилите ссылки на свои сайты, я хоть вдохновение буду черпать.

!xnn2uE3AU. Суб 09 Ноя 2013 19:29:13  #81 №333977 

>>333970

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

С точки зрения программирования все системы похожи: ты делаешь форму, подставляешь в нее всякие идетификаторы и сумму платежа. Когда пользователь оплачивает заказ, система отправляет на твой сайт POST-запрос с данными, ты либо принимаешь его либо отказываешься и если все ок, получаешь второй запрос, с уведомлением об оплате, после чего пользователя назад перекидывает. Можешь почитать тут например: https://money.yandex.ru/doc.xml?id=526025 - это у яндекса.

!xnn2uE3AU. Суб 09 Ноя 2013 19:30:36  #82 №333978 

>>333976

> В какую тематику идти?
В /web. Здесь мы изучаем PHP.

Аноним Суб 09 Ноя 2013 19:50:17  #83 №333986 

>>333965
>система залогинивания
О, а проясните за авторизацию. Сейчас сделано так - в индексном файле проверка:
if ($_SESSION['logged_in']==true) {
//показываем саму страничку
} else {
//показываем форму логина
}
Форма, соответственно, при верно введенных данных записывает true в $_SESSION['logged_in'].
Все остальные файлы имеют проверку:
if ($_SESSION['logged_in']==true) {
//показываем саму страничку
} else {
//редирект на index.php
}
Понимаю что это полный примитив, но вроде норм работает.

Аноним Суб 09 Ноя 2013 19:51:06  #84 №333989 

>>333939
>Плюс, как ты «обработаешь в бекенде» обращение к методам модели
мы просто php учим или учим и придерживаемся принципов mvc?
Ок, может я неверно понял про htmlspecialchars, я к тому чтобы работать с фреймворками и отдавать переменные шаблонизаторам, да если и без них в контроллере готовить переменные а потом отдавать готовые во вьюху.

!xnn2uE3AU. Суб 09 Ноя 2013 20:03:01  #85 №333995 

>>333986

Лучше бы вынести это в отдельный класс и писать if ($auth->isLoggedIn()), тогда если где-то ты меняешь правила или систему авторизации, ты делаешь это в одном месте, а не переписываешь весь код.

Ну а вместо

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

>>333989

Мы учим MVC, и ты наверно что-то не так понимаешь. В контроллер выносить htmlspecialchars неудобно так как:

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

$title = htmlspecialchars($project->getTitle())
$author = htmlspecialchars($project->getAuthor())
....

и еще строчек 10 такой лапши вместо того чтобы передать во вью единственную переменную $project.

- использование хелперов во вью никак не противоречит MVC, наоборот способствует порядку в коде. К хелперам относится не только htmlspecialchars, но и функции форматирования чисел, валют, дат, перевода строк, обрезки длинных строк, склонения числительных, имен и городов — все это удобнее вызывать в шаблоне.
- и наконец, как я сказал, некоторые шаблонизаторы сами автоматически делают htmlspecialchars

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

Аноним Суб 09 Ноя 2013 22:00:55  #86 №334051 

А есть здесь люди, которые разбирали исходники php?

!!8VDVWZyN Суб 09 Ноя 2013 22:31:00  #87 №334064 

Сначала я забил на свой обменник на Slim Framework, потом захотел попробовать Yii. В итоге я перенёс обменник на Yii (причем очень быстро). Теперь быдлокода меньше в 100 раз.
Но есть одна проблема:
У меня есть layouts/main.php (это основной шаблон, где подключаются js скрипты, стили)
И есть там шапка. Раньше реализовано было так:
http://dumpz.org/723747/
И всё работало. Не могу придумать, как сделать сейчас.

Аноним Суб 09 Ноя 2013 22:36:09  #88 №334066 

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

Аноним Суб 09 Ноя 2013 23:00:00  #89 №334075 

>>333253
> https://github.com/Somepony/php-wakabamark
> Ну а статей бы русских по использованию этого всего? Есть такое?

Подключаешь markUp.php (require "markUp.php"), а перед вводом (или выводом) в БД оборачиваешь переменную с текстом в функцию MarkPost(), например, MarkPost($message) или MarkPost($_post['message']).

!xnn2uE3AU. Вск 10 Ноя 2013 01:19:47  #90 №334091 

>>334064

В Yii можно получить имя контроллера и action и в зависимости от них, выделять пункт меню. Например, как тут: http://shanideveloper.blogspot.ru/2012/01/yii-how-to-get-current-controller-name.html

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


!xnn2uE3AU. Вск 10 Ноя 2013 01:21:56  #91 №334092 

>>334066

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

Если же речь о GET/POST, то просто сделай функцию вроде getQuery('name') которая внутри будет делать isset.

!xnn2uE3AU. Вск 10 Ноя 2013 01:23:54  #92 №334094 

>>334075

Лучше делать это в момент сохранения поста, и завести 2 колонки в таблице: post_source (исходынй пост) и post_html (обработанный). А то может быть дорого каждый раз при вызове делать все эти преобразования.

Аноним Вск 10 Ноя 2013 01:46:02  #93 №334100 

Анончики, выручайте (вы уже не раз мне помогали, я верю в вас). Есть софт-парсер, который шлет 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);

Аноним Пнд 11 Ноя 2013 16:47:05  #94 №334149 

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

Аноним Пнд 11 Ноя 2013 16:57:58  #95 №334152 

>>334149

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

Это еще называется «тонкие контроллеры» — старайся писать как можно меньше кода в контроллере. Почему? Потому, что код в модели, если он правильно написан, можно использовать повторно, например вызвав этот код из другого места, а код в контроллере — нельзя.

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

Аноним Пнд 11 Ноя 2013 17:07:59  #96 №334156 

>>334149

Так что по видимому ты все правильно понял.

Аноним Пнд 11 Ноя 2013 17:34:05  #97 №334162 

>>334149
Может даже не проверять. Просто получил данные, передал, получил результат валидации - отдал вюхе. Сам контролер данные не валидирует.

Аноним Пнд 11 Ноя 2013 17:44:46  #98 №334165 

>>334152
>>334162
Благодарю аноны, хорошо пояснили.

!xnn2uE3AU. Пнд 11 Ноя 2013 19:20:31  #99 №334181 

Антоны, смотрите какая офигенная идея: платные комментарии — http://tjournal.ru/paper/pay-per-comment

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

Аноним Пнд 11 Ноя 2013 20:31:55  #100 №334205 

>>333950
Ок, всё понял, приму к сведению. While там остался от прошлой реализации, как-то забыл на foreach переделать, замотался уже под конец.

Изначально сам пытался сделать через array_keys, но что-то там не получилось, уж и не помню.

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

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

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

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

Что посоветуешь, ОП?

Аноним Пнд 11 Ноя 2013 20:43:13  #101 №334207 

http://ideone.com/k8r7GE
массивы 2я задачка,что я делаю не так?

Аноним Пнд 11 Ноя 2013 20:46:29  #102 №334209 

>>334207
Перечитай про for, он работает совсем не так, как ты от него ожидаешь.

!xnn2uE3AU. Пнд 11 Ноя 2013 22:01:14  #103 №334227 

>>334205

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

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

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

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

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

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

!xnn2uE3AU. Пнд 11 Ноя 2013 22:12:57  #104 №334228 

>>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, а знак умножения ×) можешь просто скопировать из этого поста.

Аноним Втр 12 Ноя 2013 01:39:09  #105 №334266 

http://ideone.com/LaM1Pp поправил
с доп заданием ничего лучше http://ideone.com/OgwiVD
не получилось;

!xnn2uE3AU. Втр 12 Ноя 2013 10:23:38  #106 №334308 

>>334266

Задача про рост анона — все верно.

Задача про таблицу умножения:

- тут не нужен массив и foreach, используй цикл for который увеличивает переменную от 1 до 9
- чтобы сделать полную таблицу, надо использовать 2 вложенных друг в друга цикла, первый меняет допустим переменную $a от 1 до 9, второй для каждого значеия $a меняет $b от 1 до 9:


for ($a = 1; ....) {
for ($b = 1; ...) {
// пишем строчку $a * $b
}

}

!xnn2uE3AU. Втр 12 Ноя 2013 10:26:35  #107 №334309 

>>334266

Алсо, сделай чтобы таблица умножения выводилась строчками по 9 значений (для этого надо правильно поставить echo "\n"; который выводит перевод строки)

Аноним Втр 12 Ноя 2013 19:52:00  #108 №334536 

Доброкунчик, подкинь материала годного по вот этой теме http://www.php.su/functions/?cat=pcntl , а так же по управление процессами в Unix для пхп-макак. Я здесь >>333705 спрашивал про крон. Теперь мне нужно писать демон. Все классы есть, все работает, но если я смотрю на исходный абстрактный класс демона - мне становиться грустно. Помоги развеять тоску-печаль.

!xnn2uE3AU. Втр 12 Ноя 2013 20:15:01  #109 №334540 

>>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 пишешь, так что делай как там принято, там есть класс для консольных команд.

!xnn2uE3AU. Втр 12 Ноя 2013 20:17:47  #110 №334544 

vocaroo

Аноним Втр 12 Ноя 2013 20:56:51  #111 №334557 

аноны незнаю куда обратиться

пытаюсь разгадать одну херню

вот оригинал строчки:
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 строчки, так?

!xnn2uE3AU. Втр 12 Ноя 2013 21:47:39  #112 №334574 

>>334557

Может быть одна из строк и есть ключ? Написано же

> hash STRING1 with STRING2
захешировать строку1 строкой2

Аноним Срд 13 Ноя 2013 04:31:41  #113 №334648 

>>334309
http://ideone.com/1yqSg1
пойду скушаю пирожок

Аноним Срд 13 Ноя 2013 10:18:51  #114 №334660 

Гуру PHP, ай нид хэлп, суть такова: внезапно, не помню после чего, перестали работать все регексы в проекте (возвращают false и отдают пустые массивы групп). Кодировка разбираемых текстов windows-1251, IDE – Eclipse.
Перед этим игрался с сессиями (но, в итоге, выпилил их использование) и написал пару методов, пишущих массивы в XML, но они никак не связаны с регулярками и контентом.

!xnn2uE3AU. Срд 13 Ноя 2013 11:24:16  #115 №334663 

>>334648

Хорошо, только вместо этого if

> if ($b==9){

можно было поставить echo после цикла, то есть


for ($a = 1...) {
for ($b = 1; ....) {
...
}

echo "\n";
}


ну да ладно. Главное, что с циклами разобрался.

>>334660

Может ты в другой кодировке что-нибудь сохранил? Так вообще, непонятно.
Аноним Срд 13 Ноя 2013 12:55:39  #116 №334681 

> echo "\n";
Рекомендую анонам в место этого использовать echo PHP_EOL;

!xnn2uE3AU. Срд 13 Ноя 2013 12:57:12  #117 №334684 

>>334681

Чем оно лучше? \n работает везде, и пишется короче. То же самое и с DIRETORY_SEPARATOR: / работает везде и пишется короче.

Аноним Срд 13 Ноя 2013 13:05:36  #118 №334688 

>>334684
На маках другая последовательность символов. Да и просто, если язык даёт средства для автоматизации, то имхо предпочтительнее их использовать. Меня самого иногда ломает писать все эти длинные названия. По этому:
define(EOL, PHP_EOL);
define(DS, DIRETORY_SEPARATOR);

Аноним Срд 13 Ноя 2013 13:31:57  #119 №334700 

>>334688
Я конечно же хотел сказать.
> define('EOL', PHP_EOL);
> define('DS', DIRETORY_SEPARATOR);

!xnn2uE3AU. Срд 13 Ноя 2013 13:56:36  #120 №334708 

>>334688

> На маках другая последовательность символов.
На маках используется \n для новой строки (как и в Линуксе), / как разделитель каталогов (как и в линуксе). В Windows используется \r\n но \n переводит строку в консоли, и виндовые функции понимают / как разделитель каталогов.

Вопрос, зачем тогда уродовать код этими константами?

Да, когда-то в маках были свои причуды, но с выходом Mac OS X там все стало как в линуксе, а вышла Mac OS X лет 10 назад.

Или ты знаешь какой-то реальный пример, когда / или \n не работабт на современных осях?

Аноним Срд 13 Ноя 2013 15:34:22  #121 №334737 

>>334708
Анончик, я таки считаю, что код уродуется отсутствием констант. И да, используя константы эти , я не вникаю в тонкости функционирования разных ОС, но я получаю гарантию, что код будет работать так как нужно и обеспечивается обратная совместимость. Так почему бы эти константы не использовать?

!xnn2uE3AU. Срд 13 Ноя 2013 15:40:52  #122 №334744 

>>334737

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

Аноним Срд 13 Ноя 2013 15:54:33  #123 №334754 

>>334744
Анончик, я опять таки считаю, что сложнее читать
echo "\r\n";
чем
echo EOL;
Да и писать дольше.
По поводу новых разработок, твоя аргументация железная, лол. А если не разработает а модифицирует уже существующее популярное решение? Ты уверен, что в следующей версии макоси или винды не изменяться их стандарты?
Короче забей, Анон. Пиши как пишется, я никому ничего не навязываю.

Аноним Срд 13 Ноя 2013 17:07:58  #124 №334776 

>>334700
Я думаю, ты всё-таки хотел сказать
> define('EOL', PHP_EOL);
> define('DS', DIRECTORY_SEPARATOR);

Аноним Срд 13 Ноя 2013 18:07:36  #125 №334785 

Сдаю домашку.
http://viper-7.com/xdJKY9

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

Еще - может что посоветуешь почитать про объектно-ориентированное проектирование? Так чтобы совсем энтри-левел, а то тема как я понимаю необъемная.

!xnn2uE3AU. Срд 13 Ноя 2013 18:10:26  #126 №334786 

>>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");

!xnn2uE3AU. Срд 13 Ноя 2013 18:21:03  #127 №334788 

>>334785

> может что посоветуешь почитать про объектно-ориентированное проектирование?

Ну конечно же Мэтт Зандстра — PHP. Объекты, шаблоны и методики программирования

Ну еще наверно можно почитать Thinking in Java (философия Java) но это книга про Яву, она огромная, так что если ты ее начнешь читать, мы тебя точно потеряем. Еще есть книга Мартин Фаулер «Patterns of Enterprise Application Architecture» — но она для тех, у кого есть опыт работы с реальными проектами, начинающий там половину не поймет. Но можешь посмотреть из любопытства. Именно в этой книге описываются разные паттерны, фабрики и прочие вещи.

Задачку сейчас тоже проверю.

!xnn2uE3AU. Срд 13 Ноя 2013 19:01:46  #128 №334793 

>>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
Читай мануал, это полезно.

!xnn2uE3AU. Срд 13 Ноя 2013 19:03:29  #129 №334794 

>>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)

!xnn2uE3AU. Срд 13 Ноя 2013 19:06:09  #130 №334796 

>>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, так как в этом случае мы можем ловить только твои исключения.

В общем, исправь пока это, а потом проверим еще раз.

Аноним Срд 13 Ноя 2013 19:06:45  #131 №334797 

Вечер в хату, phpach.

Расскажи мне, пожалуйста, как на php эффективно работать с изображениями?

В чем суть: есть чб изображение, на изображении две метки(черные области 40х40px), Необходимо повернуть изображение так, что бы одна метка была над другой. Затем найти среднее значение цвета в некоторых заданых областях.

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

!xnn2uE3AU. Срд 13 Ноя 2013 19:18:33  #132 №334804 

>>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;
}


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

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

Вот как выглядит bigFunction с использованием исключений:


function bigFunction() {
return doDomth() + doSmth2();
}


Если в doDmth/doSmth2 произойдет ошибка, выброшенное исключение пролетит сквозь функию bigFunction наверх, и нам не надо его ловить или обрабатывать. Этот пример можно показывать особо упоротным фанатам, которые кричат что ООП тяжелый, усложненный и не нужен.

Про таблицы. Вдохновляться видом таблиц можно тут: http://dribbble.com/search?page=1&q=data+table Можно еще поискать в картинках в Google, но там половина — адский треш.

!xnn2uE3AU. Срд 13 Ноя 2013 19:20:15  #133 №334805 

>>334797

Найти как-то эти метки, найти угол линии, проведенной между ними и повернуть на этот угол.

Аноним Срд 13 Ноя 2013 19:22:01  #134 №334807 

>>334786
Ого сколько всего! Спасибо. Буду править.

>>334793
>в мануале там написано

Ну да, а дальше написано:
>This function is no longer deprecated, and will therefore no longer throw E_STRICT warnings.

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

Вообще, мануал не только читаю, но и задрачиваю. С помощью anki заучиваю основные функции с их параметрами, всякие моменты неочевидные вроде поведения self:: и static::.

Замечания по поводу вёрстки передам тян, она верстала :3

Аноним Срд 13 Ноя 2013 19:23:16  #135 №334808 

>>334805
До этого то я дошел.
Проход по всей линии в поиках черного пикселя-ну ооочень долго.

Да и как найти угол?

!xnn2uE3AU. Срд 13 Ноя 2013 19:51:37  #136 №334813 

>>334807

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

Единственный случай, когда стоит перечитать мануал — когда идешь на собеседование, например. Там любят спршивать дурацкие вопросы про то, чем отличается ++$x от $x++, про разницу операторов and и && или сработает ли if (array()) { ... } и if ("10" > "9") { ... }

Аноним Срд 13 Ноя 2013 20:19:08  #137 №334815 

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

Кстати, ответы на вопросы кажется знаю.
1. Преинкремент/постинкремент - сначала увеличивает, потом возвращает значение/сначала возвращает значение, потом увеличивает. Интересней было бы, если бы спросили что выдаст и как рассчитывается $a = 2; $a = $a += $a++;
2. Уровень приоритетности (главная разница - у 'and' он ниже чем у '=')
3. Вот тут не знаю, вроде да, т.к. массив хоть и пустой, но в списке falsy значений я его не припоминаю. Да и кажется пердолился как-то с тем, что выборка из БД была пустым массивом, а проверку if($res){} она проходила. Но не уверен.
4. Не сработает, сравнение строк идет по первому знаку (если не natcase)

Лол, меня возьмут жуниором?

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

И еще. Может кто-нибудь посоветовать халявный хостинг с php5.3+ ?

!xnn2uE3AU. Срд 13 Ноя 2013 20:41:24  #138 №334820 

>>334815

Про пустой массив (он falsy) написано тут: http://www.php.net/manual/ru/language.types.boolean.php#language.types.boolean.casting

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

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

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

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

> И еще. Может кто-нибудь посоветовать халявный хостинг с php5.3+ ?
Вроде один анон appFrog использовал. Еще есть host1free, но он легко может пару дней лежать.

!xnn2uE3AU. Срд 13 Ноя 2013 20:42:50  #139 №334821 

>>334815

Алсо, для вопросов с собеседований, тут есть список правил преобразований: http://www.php.net/manual/ru/language.types.type-juggling.php в конце

И умопомрачающая таблица сравнения типов: http://www.php.net/manual/ru/types.comparisons.php (на тот случай если спросят как сравниваются массивы с помощью == и ===)

Аноним Срд 13 Ноя 2013 21:03:45  #140 №334828 

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


>Передавать половину названия метода нехорошо (например, ты не сможешь тогда поиском найти все места где вызывается getSomething, так как в коде написано просто 'Something').

Вот про это не совсем понял, это же хелпер, он нужен только для внутренней структуры объекта. Там то там $vector->getSmth везде. Завтра перечитаю, сейчас уже голова мутная.

Остальное вроде поправил.

http://viper-7.com/TqJGRH

sageАноним Срд 13 Ноя 2013 21:47:47  #141 №334834 

Аноны, поясните что тут делать? Как мне в субклассе изменить метод? Допустим родитель имеет метод: echo "Text";. Что писать, дабы субкласс изменял метод родителя на echo "text 2"? Я по-моему что-то упустил. Маны перелопатил и не нашел примера :( Только не серчайте на ньюфажину.

!xnn2uE3AU. Срд 13 Ноя 2013 22:17:58  #142 №334842 

>>334828

Вот эта оптимизация опасна:

> $this->pay -= $employee->getSalary();
А что если между приемом на работу и увольнением у сотрудника изменился ранк или оклад? надо делать дополнительные проверки (ок, в учебной задаче нельзя менять ранг у сотрудника. Но в более реалистичной задаче наверняка понадобится. И тогда код всех тих проверок может стать запутанным и глючным).

> public function removeDepartment($name) {
Почему бы не передавать туда сам объект $department?

> Вот про это не совсем понял, это же хелпер, он нужен только для внутренней структуры объекта. Там то там $vector->getSmth везде. Завтра перечитаю, сейчас уже голова мутная.
Ну представь мы решили переименовать у класса Employee getPay в getSalary и делаем поиск по getPay (чтобы поменять название везде). 'Pay' мы не найдем и не переименуем.

>>334834

Определи в сабклассе новый метод с таким же именем.

!xnn2uE3AU. Чтв 14 Ноя 2013 01:29:45  #143 №334874 

>>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() — там можно обойтись без перебора всего массива.

Аноним Чтв 14 Ноя 2013 14:44:22  #144 №334939 

>>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? Но в этом же случае емнип массив всё равно будет перебираться, просто за кадром.

Аноним Чтв 14 Ноя 2013 14:47:14  #145 №334941 

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

!xnn2uE3AU. Чтв 14 Ноя 2013 15:31:26  #146 №334962 

>>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

Для этого мы и решаем задачки. Косяки, да, подмечаю, так как ООП не самая простая вещь и многие в нем путаются, а знать его надо обязательно (и есть книги/курсы, где его не изучают, что печально).

Аноним Чтв 14 Ноя 2013 16:16:26  #147 №334971 

Как грамотнее устанавливать 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: Производительность, говнокод.

!xnn2uE3AU. Чтв 14 Ноя 2013 16:24:53  #148 №334973 

>>334971

Вариант с onclick="..." — ОК (так любит делать например вконтакте)

Вариант 2 и 3 с $('.delete').click — отстой, так как ты сначала ищешь кучу элменетов и ставишь кучу обработчиков. А если бы автор кода вместо изучения jQuery изучил яваскрипт и DOM ( в чудесном учебнике http://learn.javascript.ru/event-delegation ) то узнал бы, что события всплывают и можно один поставить обработчик на родительский элемент (и да, в этом случае динамиечски добавляемые элементы тоже будут работать).

Так что либо прописывай onclick="" либо ставь один обработчик на родителя. И еще, я бы советовал использовать для кнопки button: он гораздо удобнее, чем span, плюс он выделяется табом, не разрешает выделять на нем текст и вообще ведет себя как настоящая кнопка.

!xnn2uE3AU. Чтв 14 Ноя 2013 16:28:05  #149 №334974 

>>334971

Насчет jQuery, если используешь его, то и обработчик удобно ставить с помощью него: $('#table').on('click', '.delete-row', function (e) {
...
}); — по моему в новом jQ это делается так. Строчка '.delete-row' пропускает только события, возникшие на кнопке, а не в любом месте таблицы.

Аноним Чтв 14 Ноя 2013 17:32:51  #150 №334980 

>>334973
Спасибо, пожалуй, c onclick='' проще всего сделать. А если несколько функций надо повесить, решение со вспомогательной функцией покатит?
onclick='temp()' где
function temp() {
deleteRow();
recount();
ajax();
}
А то onclick='deleteRow(); recount(); ajax();' как-то вырвиглазно выглядит, хотя работает. Про addEventListener, attachEvent читал, там ад с кроссбраузерностью, передачей this и аргументов, не хотеть.
И вдогонку: есть ли смысл дополнительно прописывать id для инпута чтобы брать его в JS с помощью getElementById(), если его можно взять getElementsByName()[0]. По айди вроде как быстрее, но в данном случае имя на форме уникально и всего одно.

!xnn2uE3AU. Чтв 14 Ноя 2013 17:48:48  #151 №334984 

>>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

Аноним Чтв 14 Ноя 2013 20:37:15  #152 №335025 

Объясните мне пожалуйста, зачем нужны абстрактные классы? http://www.php.net/manual/ru/language.oop5.abstract.php <-- здесь вообще не говорится зачем они нужны (а нахуя?) а вот здесь первый ответ вроде 27 человек оценили, но я ничего не понял. Читал ответы на stackoverflow и на askdev но всё равно не пойму зачем их использовать. Может кто-то попытается объяснить на пальцах? Помогите анончики, вы последняя надежда.

Cупер дабл Аноним Чтв 14 Ноя 2013 20:51:26  #153 №335033 

У анона выпало 6 и 6
У компьютера 6 и 6
Сума в анона 12
Сума у компьютера 12
2 дабла!

Аноним Чтв 14 Ноя 2013 21:02:24  #154 №335038 

>>335025
ОНА НАСТОЯЩАЯ!!!

!xnn2uE3AU. Чтв 14 Ноя 2013 21:28:08  #155 №335039 

>>335033

Да, это редко бывает.

>>335025

Абстрактный класс — это класс, объект которого нельзя (или нет смысла) создать. Обычно а.к. используется в качестве базового класса, от которого наследуются уже не-абстрактные (=конкретные) классы.

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

Пример — программа про ООО Вектор: http://viper-7.com/TqJGRH — здесь класс Employee просто обязан быть абстрактным (но это почему-то не сделано), так как надо создавать один из его наследников.

>>335038

Да, и судя по виду местности, из нашей страны.

Аноним Птн 15 Ноя 2013 01:13:31  #156 №335082 

https://github.com/Somepony/pdd.yandex-mail-register

Аноним Птн 15 Ноя 2013 03:38:09  #157 №335106 

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

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

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

Сохранение в html. Сайт о шарах Аноним Птн 15 Ноя 2013 08:42:26  #158 №335120 

Аноны, а двач ведь схороняет страницы в html, чтобы грузить быстрее и независимо от базы, так? У двача все просто, можно разложить треды по доскам (в папках) и радоваться жизни. А если сайт, например, о шарах. Шары бывают большие, средние и маленькие, а ещё красные, чёрные, синие и коричневые. Под цвет и размер есть две разные менюшки, сделать размер или цвет главным параметром (чтобы вложить в него другие) нельзя, так как надо в любой момент иметь возможность вывести все красные шары или все маленькие или все большие коричневые. Как разложить их? Дублировать две вложенные структуры? Это наверное быдлокод и может усложнить жизнь раскручивающему. Может какие-то номера дать отдельным шарам (образно, страниц с описанием товара шар, статьям о шарах, контактных данных шаров) и сохранять их по номерам, а в структуре хранить только основные страницы каталога?

!xnn2uE3AU. Птн 15 Ноя 2013 10:53:54  #159 №335140 

>>335120

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

Параметры шара в WP можно сделать тегами, тогда одной статье можно назначить 2 тега — «красные шары» и «большие шары». Или же, если рчь о Друпале, можно сделать у шара 2 категории через CCK — «цвет» и «размер». Ну и менюшки после этого можно прикрутить любые.

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

> чтобы грузить быстрее и независимо от базы, так?
База есть на любом хостинге за 50 рублей в месяц. Плюс, такой подход, как я понимаю, создает огромную нагрузку на диск при активном постинге.

!xnn2uE3AU. Птн 15 Ноя 2013 10:55:33  #160 №335141 

>>335120

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

Аноним Птн 15 Ноя 2013 11:17:41  #161 №335143 

>>335038
Среднетян из хохлостана.
http://lisavasya.deviantart.com/

!xnn2uE3AU. Птн 15 Ноя 2013 12:18:50  #162 №335148 

>>335143

Да, няшная.

Аноним Птн 15 Ноя 2013 15:41:58  #163 №335166 

>>335120
>грузить быстрее и независимо от базы
Либо отправить запрос в базу и узнать имя html документа, где эти данные лежат в файловой системе, а затем отправить клиенту 302-й редирект (не 301-й, т.к. это не жёсткий редирект, а простое сообщение о том, что данные физически лежат в другом месте), чтобы клиент их забрал -

- либо никак.

!xnn2uE3AU. Птн 15 Ноя 2013 15:45:41  #164 №335169 

>>335166

Что за наркоманство ты пишешь? Чтобы ускорить сайт на тяжелой CMS или вордпрессе, не нужны никакие самописные кривые системы на файлах.

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

Аноним Птн 15 Ноя 2013 16:07:36  #165 №335172 

>>335169
Дорого. У меня хостинг в "Зеноне", они сами зеркалируют сколько угодно файлов на какое-то количество зеркал, и отдают файлы с них. А чтобы поставить nginx и memcahce, надо... надо... иметь хоть какой-то доход от сайта, наверное! А у меня его нету.

!xnn2uE3AU. Птн 15 Ноя 2013 16:12:30  #166 №335174 

>>335172

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

Если тебе нужен статический сайт на файлах без БД, не надо писать код, ты можешь сделать так:

- найти и заюзать программу-генератор статических сайтов (вроде бы фронтпейдж так умеет, рисуешь в нем сайт а он генерирует HTML)

- сделать на локалхосте сайт на любой CMS, какой-нибудь программой типа супер-пупер-сайт-даунлоадер скачать его в папку в виде кучи HTML файлов и их выложить на хостинг. При обновлении повторить.

!xnn2uE3AU. Птн 15 Ноя 2013 16:14:28  #167 №335175 

>>335172

Насчет генераторов сайтов: тут их много: http://habrahabr.ru/post/93499/

Аноним Птн 15 Ноя 2013 16:19:40  #168 №335177 

>>335174
>> фронтпейдж

Аноним Птн 15 Ноя 2013 18:57:54  #169 №335216 

>>335120
>>335140
Анон, а если я хочу велосипед? База есть, просто я предпочитаю нагрузку на диск нагрузке на базу. Скорость постинга в тысячу раз реже скорости чтения.

Аноним Птн 15 Ноя 2013 19:02:43  #170 №335218 

>>335216
Аноны предпочитают нагрузку на память нагрузке на диск (даже те, кто предпочитает нагрузку на диск нагрузке на базу), такие дела.

Аноним Птн 15 Ноя 2013 19:24:30  #171 №335222 

Что можешь посоветовать в обучение в дальнейшим ?
Имеется основная база(без ООП) со знаниемя mysql, etc.

!xnn2uE3AU. Птн 15 Ноя 2013 19:38:23  #172 №335225 

>>335222

ООП и фреймворки, они везде нужны.

Также, научиться HTML/CSS/JS, не на уровне крутого фронтендщика, а на базовом, уметь что-то поправить.

!xnn2uE3AU. Птн 15 Ноя 2013 19:40:12  #173 №335226 

>>335216

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

Аноним Птн 15 Ноя 2013 21:34:54  #174 №335257 

Если @ - это плохо, то как можно изящно заменить
<input type='text' value="<?=@$_POST['foo']>">
в форме, так чтобы если валидация не пройдена значения там сохранялись?
Или в готовом варианте просто выключить эти нотисы?

!xnn2uE3AU. Птн 15 Ноя 2013 21:38:25  #175 №335260 

>>335257

Использовать @ — плохо
Выключать нотисы — дважды плохо

Правильное решение: сделай функцию post('foo', 'defaultValue') или сразу post('foo')

Алсо не забудь про экранирование:

<?= htmlspecialchars(post('foo')) ?>

Паста про экранирование и XSS: https://gist.github.com/anonymous/52adda0113428b274c64

Аноним Птн 15 Ноя 2013 22:16:37  #176 №335275 

>>335225
Какие фреймворки можешь посоветовать ?

!xnn2uE3AU. Птн 15 Ноя 2013 22:31:11  #177 №335279 

>>335275

Yii, Symfony 2

Аноним Суб 16 Ноя 2013 07:53:23  #178 №335318 

На словах ты Лев Толстой
не могу понять как решать эту задачку,halp

Аноним Суб 16 Ноя 2013 11:10:59  #179 №335327 

Задачка про школьника и айфон. Скажем, я выполнил задание, но решил пойти дальше и подсчитать сколько школьнику пришлось переплатить. Т.е. надо посчитать разницу между $totalPayment и суммой заёма = 40000. Я не смог придумать ничего умнее, чем создать новую переменную $loan и присвоить ей значение 40000 (4-ая строчка). А как можно это сделать не засоряя пространство имен лишней переменной? В каждой итерации цикла мы увеличиваем $currentBalance, а как можно обратиться к первоначальному значению, не создавая новую переменную?

http://codepad.org/1oi7ksFd

Аноним Суб 16 Ноя 2013 11:19:27  #180 №335329 

Задачка про школьника и айфон. Скажем, я выполнил задание, но решил пойти дальше и подсчитать сколько школьнику пришлось переплатить. Т.е. надо посчитать разницу между $totalPayment и суммой заёма = 40000. Я не смог придумать ничего умнее, чем создать новую переменную $loan и присвоить ей значение 40000 (4-ая строчка). А как можно это сделать не засоряя пространство имен лишней переменной? В каждой итерации цикла мы увеличиваем $creditBalance, а как можно обратиться к первоначальному значению, не создавая новую переменную?

http://codepad.org/1oi7ksFd

Аноним Суб 16 Ноя 2013 11:47:55  #181 №335331 

http://codepad.org/5rIZvMMa

Правильно ли я использую префиксный декремент? Или он тут не нужен? Ведь сначала увеличивается сумма на счету, а потом выполняется инкрементирование $i++. В следующий раз условие цикла не выполняется, но $i то уже увеличилось на единицу.

Аноним Суб 16 Ноя 2013 13:37:44  #182 №335336 

Анон, а научи меня в mysql! Всегда пользовался двумя типами полей, никогда не заморачивался с индексами, транзакциями, связями таблиц, что там еще есть страшного, вообще не знаю, зачем нужна половина настроек phpmyadmin - тем более не представляю, логические поля делаю целочисленными с длиной 1, с перечислениями вообще не разбирался, с типами таблиц тем более. Какая есть годнота на русском языке по этой теме? Чтобы от и до желательно, как, где, почему, а главное, что это даст (желательно иметь подробную книгу с разбором принципов, может даже реляционной модели вообще, но при этом чтобы был также упор на объяснение, зачем это все нужно и что это нам даст. Это - каждый конкретный случай).
>>335327
какая няшка, я бы проткнул ее своей пикой. Только современная заколка и низ штанов в ноль портит впечатление. Косплеит кого-то? И еще вопрос: меч пластмассовый? Если нет, то как она его держит так легко своей хлипкой ручкой, если он весит не меньше грамм 900, а балансом ему, по всей видимости, выступает гарда?

!xnn2uE3AU. Суб 16 Ноя 2013 15:48:48  #183 №335349 

>>335318

Берешь первый массив слов. C помощью mt_rand генерируешь число от 0 до (число элементов - 1). Потом берешь элемент с индексом, равным этому числу и таким образом получаешь случайное слово из массива.

Так же делаешь и с остальными массивами.

Потом из слов собираешь строчки.

Аноним Суб 16 Ноя 2013 16:00:22  #184 №335351 

>>335336
> Косплеит кого-то?
Ути какой ньюфажик

!xnn2uE3AU. Суб 16 Ноя 2013 16:04:08  #185 №335352 

>>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;

Это копипаста, копипаста — зло. Лучше бы ты один раз посчитал и положил в переменную, а не копипастил формулы.

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

!xnn2uE3AU. Суб 16 Ноя 2013 16:11:10  #186 №335355 

>>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...";
}
?>


!xnn2uE3AU. Суб 16 Ноя 2013 16:22:03  #187 №335356 

>>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

!xnn2uE3AU. Суб 16 Ноя 2013 16:36:08  #188 №335363 

>>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

!xnn2uE3AU. Суб 16 Ноя 2013 16:38:43  #189 №335364 

>>335336

А, и еще есть такая вещь как UNIQUE INDEX. С помощью уникального индекса можно запретить вставлять в таблицу одинаковые значения (например, 2 пользователей с одинаковым логином).

sageАноним Суб 16 Ноя 2013 19:08:28  #190 №335388 

Аноны. Вопрос. Как сделать так - Echo запрос ввода данных, пауза, пока данные не введут и не нажмут Enter, запрос других данных, снова пауза пока не введут и не нажмут Enter. Так около 4х раз, И УЖЕ ПОСЛЕ - выполнение скрипта дальше. Помогите?
Это все реализовываю в виде консольного скрипта.
Можно сделать с формами, но мне так не нужно.

Аноним Суб 16 Ноя 2013 19:33:32  #191 №335398 

доброанон, помоги
Почему может не проходить запрос вида
UPDATE table SET param1='$param1', time=$time WHERE param2='$param2' AND param3='$param3'
пробовал играться со скобками у AND, пробовал ставить-убирать кавычки - толку никакого, запрос просто не проходит, при этом ошибки не выдается никакой. Названия таблицы, полей правильные.
Попытка спросить о причинах ошибки у mysql_error($result) ничем не заканчивается, он говорит, что ему передано логическое значение, когда он хотел получить ресурс. Попытка распечатать $result дает нихера. Перед этим с той же базой и почти теми же параметрами SELECT проходит спокойно и без ошибок. Практически такой же код с UPDATE раньше с другой базой тоже работал прекрасно.

!xnn2uE3AU. Суб 16 Ноя 2013 19:38:14  #192 №335400 

>>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

!xnn2uE3AU. Суб 16 Ноя 2013 19:45:26  #193 №335402 

>>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));

Аноним Суб 16 Ноя 2013 19:47:27  #194 №335403 

>>335363
не пугайте народ

Enum внутри все равно преобразуется либо к tinyint либо к int.
Даты настолько разные, что ОБЯзательно читать мануал по каждой, т.к. скорость поиска разница в сотни раз.
И ОБЯзательно помнить, что поле NULL занимает дополнительный байт и при обработке полей с нулами применяются дополнительные просчеты.
varchar запомните что это ДИНАМИЧЕское поле, которое хранит вначале байт длинны, это очень сильно отразится на больших обьемах поиском в этих полях, поля постоянной длины намного быстрей работают.

Лучше все запомните пару важный правил
1) стремиться делать выборки только по индексу и только по числу (инт, бигинт)
2) избегайте Null-ов и динамических полей насколько возможно

sageАноним Суб 16 Ноя 2013 19:51:37  #195 №335406 

>>335400
Огромное тебе спасибо ОПушка. Добра :3

!xnn2uE3AU. Суб 16 Ноя 2013 20:06:05  #196 №335415 

>>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, а не применять такие советы бездумно. Научиться смотреть статистику использования разных буферов и делать выводы.

Аноним Суб 16 Ноя 2013 20:31:11  #197 №335417 

>>335415
ооо вижу ты совсем не знаком с приличными проектами на мускуле,
где ты увидел что предлагают использовать свои форматы енума?
чет я вижу только предложения использовать tinyint как вариант и не более...
С датами сразу вижу ты не работал, когда наберешь хотябы 5-10 миллиончиков, узнаешь насколько DATETIME медленней TIMESTAMP-а,
и опять же ГДЕ вы ВИДИТЕ изобретателя велосипеда?
было только предложено прочитать какая именно дата подойдет именно в вашем случае.

Для начинающих нулы может и пофиг, потом когда вы наберете только истории хотябы на 400гб, узнаете что такое нулы которые вам не нужны вообще. Если вам нужен нулл то спорить нечего, но когда пишут
time int defaul 0
то подумайте зачем вам нул который тут не нужен и будет только мешаться.

И еще открою тебе тайну, раз не знаешь, индексы по строке индексируют только 1 символ, а представь когда будет 5млн записей по 1символу, вот тут научитесь пользоваться unsignet int not null и хеши по b-tree ...

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

Аноним Суб 16 Ноя 2013 21:52:15  #198 №335425 

Привет, парни. Я анон, делавший борду в прошлых двух тредах, решил прикрутить к ней систему пользователей. Типа как у людей: админы, модераторы, абу, все дела.
Идея, я ёё нашел где-то на стэковерфлоу, следующая:
пользователь заходит в систему, его имя и, возможно, ещё какие-то данные пишутся в сессию. Если он при входе отметил пункт "запомнить меня", то дополнительно пишутся куки с именем и случайно сгенерированным при регистрации токеном. В следующий раз проверяется наличие кук. если имя и токен совпадают с указаными в таблице происходит авторизация.
ПХП-анон, можешь посмотреть мой код? Там все по-сути происходит с в трех файлах - Application/Model/User.php,
Application/Controller/User.php и Application/Core/ Auth.php

Аноним Суб 16 Ноя 2013 21:53:49  #199 №335426 

>>335425
Ах да, ссылку забыл:
https://github.com/melanchthon/board

sageАноним Суб 16 Ноя 2013 22:17:17  #200 №335437 

>>335400
>дескриптор потока
Пожалуйста объясни в двух словах или дай ссылочку где почитать, что это? Погуглил и не много не понял, а может и не то нагуглил. Спасибо :3

Все-тот-же-анон

!xnn2uE3AU. Суб 16 Ноя 2013 22:46:48  #201 №335444 

>>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-архива и много чего еще.

!xnn2uE3AU. Вск 17 Ноя 2013 00:27:44  #202 №335456 

>>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 минут, показываем капчу.

!xnn2uE3AU. Вск 17 Ноя 2013 01:06:15  #203 №335464 

>>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() так как пользователь может нечаянно впечатать пробел в начале или конце и не заметить.

Аноним Вск 17 Ноя 2013 11:37:03  #204 №335507 

про палиндромы решил вот

http://ideone.com/QrVm4z

Аноним Вск 17 Ноя 2013 13:56:45  #205 №335523 

спасибо за задачки, Опушка

!xnn2uE3AU. Вск 17 Ноя 2013 16:16:27  #206 №335540 

>>335507

Молодец, программа работает правильно. Едиснтвенное, вместо этого:

($lower == $reversed) ? $result = "Это палиндром" : $result = "Не палиндром";

Лучше нормально использовать if/else (ради читабельности). Тернарный оператор обычно используют как выражение, а не как отдельную команду. Ну или можно переписать это в виде:

$result = ($lower == $reversed) ? "Это палиндром" : "Не палиндром";

Так сразу видно, что это команда присваивающая переменной result какое-то значение.

Аноним Вск 17 Ноя 2013 19:16:28  #207 №335580 

Присоединяюсь к вашему клубу. Вот мое решение задачи про айфон в кредит
http://codepad.org/fxTTiwWS

Аноним Вск 17 Ноя 2013 19:24:46  #208 №335582 

>>335580
Мое решение задачи про банк в догонку http://ideone.com/rvMBeo

!xnn2uE3AU. Вск 17 Ноя 2013 20:26:56  #209 №335592 

>>335580

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

Аноним Вск 17 Ноя 2013 20:50:55  #210 №335597 

Проясните за die/exit, почему-то вижу их буквально в каждом коде во всех местах, хотя не понимаю что такого полезного в этих операторах, кроме сообщения про ошибки. Где надо использовать?

!xnn2uE3AU. Вск 17 Ноя 2013 21:44:08  #211 №335599 

>>335597

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

Аноним Пнд 18 Ноя 2013 10:27:49  #212 №335682 

>>335597
>рождённый, чтобы умирать

!xnn2uE3AU. Пнд 18 Ноя 2013 10:45:09  #213 №335685 

>>335682

Это же отлично:

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

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

Аноним Пнд 18 Ноя 2013 12:13:34  #214 №335690 

>>335349
http://ideone.com/pNXsox как оно?

!xnn2uE3AU. Пнд 18 Ноя 2013 12:20:32  #215 №335693 

>>335690

Все верно, только вот strtr($word1,$st1); — это ты наверно забыл убрать, от этой команды ошибки идут из-за неопределенных переменных.

Аноним Пнд 18 Ноя 2013 12:37:24  #216 №335704 

>>335693
ага.
>(число элементов - 1)
а зачем -1.
хард моде: переделай под стиль Маяковского
у этого ведь нет програмного решения?

!xnn2uE3AU. Пнд 18 Ноя 2013 13:27:57  #217 №335724 

>>335704

> а зачем -1.
Сделай массив из 5 элементов, например, сделай var_dump($array) и посмотри какие индексы у элементов. В массиве из 5 элементов нет элемента с индексом 5, они нумеруются с 0 до 4.

> у этого ведь нет програмного решения?
Нет, наверно. Надо поменять исходные слова на более подходящие (жесткие и решительные) и схему предложения, у Маяковского обычно стихи всякими столбиками и треугольниками идут.

Аноним Пнд 18 Ноя 2013 16:20:40  #218 №335761 

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

http://ideone.com/ixAx6y


!xnn2uE3AU. Пнд 18 Ноя 2013 16:48:14  #219 №335764 

>>335761

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

Если ты хочешь удалить символы, то вместо preg_split + implode проще использовать preg_replace (или ее ты пока не изучил?) или strtr.

Аноним Пнд 18 Ноя 2013 16:59:11  #220 №335768 

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

Аноним Пнд 18 Ноя 2013 19:30:24  #221 №335827 

Как лучше хранить много картинок, например, обложек книг для каталога?
1. Все в одной папке, с рандомными именами типа be677264d0_poster.png, be677264d0_thumb.png + отдельное поле в базе с именем.
2. Каждую в отдельной папке вида /books/.$title/ со стандартными именами типа poster.png, thumb.png. Поле в базе при этом не нужно, проверки существования и генерации имен тоже.
Второй вариант выглядит намного изящнее, но нет ли каких-то подводных камней с производительностью из-за множества папок?

!xnn2uE3AU. Пнд 18 Ноя 2013 19:36:45  #222 №335830 

>>335827

> нет ли каких-то подводных камней с производительностью из-за множества папок?
Подводные камни есть когда в каталоге много файлов и ты пытаешься его открыть каким-нибудь файловым менеджером — тормозит.

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

/books/162/162354.png
/books/102/102500.png

Если не надо лезть в базу, это плюс.

Аноним Пнд 18 Ноя 2013 19:36:46  #223 №335831 

Есть переменная. В ней html текст.
В тексте абзацы, бр теги и картинки. Другое исключено (strip_tags же)

Мне надо сделать:
1. так, чтобы каждая картинка была выкачана в папку /images
2. Заменен путь этой картинки на локальный адрес

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

Пишу свой RSS ридер, обучаюсь.

!xnn2uE3AU. Пнд 18 Ноя 2013 19:38:35  #224 №335833 

>>335831

1) можно регулярками (preg_match_all, preg_replace) найти URL картинок и регулярками же заменить
2) можно загрузить HTML в DOM дерево (DomDocument::loadHtml) и в дереве искать все элементы IMG, после чего поменять им аттрибут src и преобразовать назад в HTML.


Аноним Пнд 18 Ноя 2013 19:39:36  #225 №335834 

>>335833

И еще, надо чтобы текст был гарантированно в utf-8, кодировка на входе может быть ЛЮБАЯ. Как сделать?

!xnn2uE3AU. Пнд 18 Ноя 2013 19:40:30  #226 №335835 

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

Просто интересно, проще это чем в PHP или сложнее.

!xnn2uE3AU. Пнд 18 Ноя 2013 19:41:31  #227 №335837 

>>335834

Определяешь кодировку на входе (по заголовку Content-Type, тегу meta charset и другим правилам описанным в стандарте HTML) и преобразуешь в utf-8 через iconv()

Аноним Пнд 18 Ноя 2013 19:41:35  #228 №335838 

>>335833

а выкачать картинки как?

Т.е. мне надо гуглить регулярные и их учить, а по DOM что гуглить?

Аноним Пнд 18 Ноя 2013 19:44:29  #229 №335842 

>>335837

на входе xml же с RSS

!xnn2uE3AU. Пнд 18 Ноя 2013 19:56:18  #230 №335845 

>>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»

Я написал может не очень понятно, так что напиши если что-то не понял.

!xnn2uE3AU. Пнд 18 Ноя 2013 19:59:32  #231 №335847 

>>335842

Плюс, как я понимаю, если ты используешь DOM:

$dom = new DOMDocument('1.0', 'utf-8');
$dom->loadXml('....');

то он сам решает проблемы с кодировками. Мануал по DOM (большой): http://www.php.net/manual/ru/class.domdocument.php



Аноним Пнд 18 Ноя 2013 21:42:43  #232 №335909 

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

Аноним Пнд 18 Ноя 2013 21:46:24  #233 №335910 

>>335845

Смотри, дружище.
xml имеет кодировку utf-8
Файл с php кодом тоже.
Беру из файла и пишу в бд. В бд - пикрелейтед.

utf8_encode() не помогает.
как решить эту проблему?

!xnn2uE3AU. Пнд 18 Ноя 2013 21:52:20  #234 №335912 

>>335910

Ну так может у тебя в БД через одно место кодировка выставлена? Ты запрос SET NANES utf8 при соединении с БД делаешь или надеешься на авось, что все само правильно выставится?

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

Аноним Пнд 18 Ноя 2013 22:03:26  #235 №335919 

>>335912

Делаю

> $link = mysql_connect('localhost',$user, $pass) or die ('пиздец нахуй!'.mysql_error());
>mysql_query('SET NAMES UTF-8');

!xnn2uE3AU. Пнд 18 Ноя 2013 22:08:36  #236 №335923 

>>335919

Вроде бы SET NAMES utf8 без знака минус.

Аноним Пнд 18 Ноя 2013 22:22:10  #237 №335930 

ОП, помоги пожалуйста установить 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 так и не добрался пока.

Аноним Пнд 18 Ноя 2013 22:28:08  #238 №335933 

>>335464
Про привязку к IP в-целом понятно. Но вот как привязать к подсети непонятно нихуя.
Смотри, насколько я понимаю IP-адрес состоит из двух частей: адрес подсети/адрес узла, аналогия - название улицы/номер дома. Адрес подсети можно высчитать из IP зная маску подсети - она для каждой подсети своя, я всё правильно понял?
Ну и собственно вопрос, я могу узнать айпи из $_SERVER['REMOTE_ADDR']? но как мне узнать из него собственно адрес самой подсети, не зная маски? Ткни носом, пожалйста, не могу разобраться.

Аноним Пнд 18 Ноя 2013 23:03:05  #239 №335960 

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

Аноним Пнд 18 Ноя 2013 23:19:15  #240 №335976 

>>335930
Гугли wamp.

Аноним Пнд 18 Ноя 2013 23:28:32  #241 №335980 

>>335976
Нет, это что-то на уровне Денвера. Я сейчас смотрю специалиста, дошел до момента работы с базами данных, там идет работа из под командной строки. Денверский же MySQL настроен как-то по другому, или я пока не могу разобраться во всем этом из-за недостаточного уровня знаний. Уж лучше установить все как и у преподавателя, дабы не путаться и не ломать голову. Застопорился даже на моменте подключения к самой БД MySQL, решил установить все по отдельности, но уже два дня вместо занятий ломаю голову над установкой.

!xnn2uE3AU. Пнд 18 Ноя 2013 23:33:12  #242 №335984 

>>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 адреса. Это будет неточно, но в большинстве случаев работать как нам надо.

!xnn2uE3AU. Пнд 18 Ноя 2013 23:47:48  #243 №335990 

>>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.

!xnn2uE3AU. Пнд 18 Ноя 2013 23:49:56  #244 №335993 

>>335930

Еще советы: если при запуске Апача с Php пишется «не найдена какая то библиотека попробуйте переустановить прилоежние» то это скорее всего у тебя какая-то папка важная не добалена в PATH. Добавь, не спеша перезагрузись и продолжай эксперименты.

Вот еще пасты, может помогут:

http://gist.github.com/anonymous/2dfa134fe20d9cf91bbe Как научиться пользоваться командной строкой
http://gist.github.com/anonymous/946f4f1830be3955fe17 Как установить Апач (старая)

!xnn2uE3AU. Пнд 18 Ноя 2013 23:57:44  #245 №335999 

>>335960

А что писать гостевую? У нас есть задачка «запрограммировать имиджборду», причем верстка уже готовая есть, смотри какая: https://github.com/codedokode/board-markup

Не хочешь попробовать?

Уровень: нужно знать PHP и SQL хотя бы немного
Цель: научиться писать приложения, а не простые скрипты, познакомиться с MVC, повысить практические навыки.

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

Нужно использовать ООП.

Аноним Втр 19 Ноя 2013 00:01:05  #246 №336002 

>>335990
Да, версия совместима с Апачем. Библиотека для Апач2.2 имеется, PHP автоматически прописывает к ней путь, когда при установке указываю расположение httpd.conf. Я пробовал качать Апач с apachelounge, но так и не понял что они мне предлагают, так как вместо инсталятора скачались какие-то папки и пару файликов. Что с ними делать так и не понял.
Да, про поддержку старых и новых версий уже читал. На официальном сайте Апача говорят лучше качать Апач2.2, чтобы запустить его с VC6. Как же все запутано. Очень жаль, что на уроках в Специалисте не показали так сказать наглядную установку, а показали лишь на картиночках. А про не найденную библиотеку не писал, писал только про "Специфическую ошибку 1". Сколько гуглил - ответы были что мол был невнимателен, вместо одной папки в пути прописал другую, исправил и все заработало. 300 раз перепроверил, какие статьи только не попробовал, так и не получилось. Ладно, спасибо, ОП. Буду сносить ХР, поставлю семерку и буду пробовать на ней с более новыми сборками.

!xnn2uE3AU. Втр 19 Ноя 2013 00:10:39  #247 №336004 

>>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 на рабочем столе или в меню пуск для удобства.

| Буду сносить ХР, поставлю семерку и буду пробовать на ней с более новыми сборками.
только не думай, что это избавит от необходимости разбираться.

Аноним Втр 19 Ноя 2013 00:20:37  #248 №336006 

>>336004
Как все запутанно. С каждым днем чувствую себя все более и более криворукой макакой, тяжело усваиваю материал. А тут еще и с установкой софта такой фейл, не понимаю, как люди по книжкам это читают и делают.
Спасибо за перевод, так будет гораздо проще.
А про игры нет, в них я совсем не играю, разве что майнкрафт иногда. Большинство времени провожу тупо скроля интернеты, бессмысленно тратя время, поэтому собственно решил осваивать данный язык. Паскаль в быдловузике совсем не вдохновляет, но вроде как дал неплохую почву для какого-никакого понимания других языков.

Аноним Втр 19 Ноя 2013 01:23:34  #249 №336036 

Доброанон, посоветуй. Есть сайт. Сайт наполняется статьями. Мне сказали, причем весьма уверенно, что для поисковой оптимизации очень хорошо в адресной строке иметь написанное транслитом название каждой статьи. То есть вместо page.php?id=12345 нужно делать page.php?name="kak zavyazivat galstuk" и потом делать это красиво через mod_rewrite. Здесь id и name - соответственно номер и название статьи. Дак вот, правда ли это, что так делать лучше (все популярные сайты и правда так делают) и как это реализовывать? Вводить специально транслитную версию отдельным полем в БД или использовать русское имя, но какими-то функциями перегонять его в транслит для адресной строки? Еще вопрос, если в БД куча статей, запрос, содержащий where name='kak zavyazivat galstuk' ведь должен сильно тормозить? Это же поиск по тексту почти. Вообщем, как делать правильно, расскажи, посоветуй.

Аноним Втр 19 Ноя 2013 04:23:50  #250 №336065 

>>336006
Запутанно когда ставишь по советом двачей..прочитай хорошую книжецу про unix и все распутается у тебя

Аноним Втр 19 Ноя 2013 09:51:48  #251 №336080 

>>335540
Почему когда вводим другую фразу-не палиндром,все равно пишет что это палиндром,где-то косяк,помоги найти :3

Аноним Втр 19 Ноя 2013 10:14:05  #252 №336082 

>>336080
самофикс,точка лишняя стояла

Аноним Втр 19 Ноя 2013 10:22:34  #253 №336086 

>>336082
Все равно не работает :(

!xnn2uE3AU. Втр 19 Ноя 2013 10:26:01  #254 №336087 

>>336086

Что-то я проглядел это.

$reversed .= mb_substr($lower, $i, 1);

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

$reversed = mb_substr() . $reversed;

Или же переделай цикл, чтобы он шел не с первой до последней буквы. а с последней до первой.

Аноним Втр 19 Ноя 2013 11:39:22  #255 №336110 

>>336087
Спасибо,доброкун

Аноним Втр 19 Ноя 2013 11:56:07  #256 №336114 

>>336036
>>336087
доброанон, выручи.

!xnn2uE3AU. Втр 19 Ноя 2013 12:04:30  #257 №336115 

>>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 символов.

!xnn2uE3AU. Втр 19 Ноя 2013 12:07:16  #258 №336117 

>>336036

У меня есть еще паста про URL (с точки зрения человека, а не робота): https://gist.github.com/codedokode/772a4ccc03e41d6b7cba

Аноним Втр 19 Ноя 2013 12:10:14  #259 №336118 

>>336117
>>336115
спасибо, бро. Я именно про это и хотел спросить. То есть все обычно ставят индекс по первым символам особого текстового поля и хранят эти транслитные адреса в нем, так?

!xnn2uE3AU. Втр 19 Ноя 2013 12:11:09  #260 №336119 

>>336118

Да.

!xnn2uE3AU. Втр 19 Ноя 2013 13:18:43  #261 №336138 

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

Изучайте.

Аноним Втр 19 Ноя 2013 14:20:35  #262 №336152 

чего-то никак палиндром не получается,что я делаю не так
http://ideone.com/NGgItv

!xnn2uE3AU. Втр 19 Ноя 2013 14:47:32  #263 №336155 

>>336152

$half2=strrev($half1);

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

Аноним Втр 19 Ноя 2013 20:41:46  #264 №336242 

Ебался-ебался я со второй задачей на регулярки, и вот только сейчас доделал: http://ideone.com/ZGLiNh
.
А всё потому, что никто блджад в этом сраном мануале не потрудился сообщить о том, что функция preg_match_all, если ей передать флаг PREG_OFFSET_CAPTURE будет выдавать смещение в БАЙТАХ а на в символах...
Я очень долго пытался вкурить почему же всё работает не так, как надо.

Аноним Втр 19 Ноя 2013 20:48:26  #265 №336246 

>>336242
вот прогнал через http://beta.phpformatter.com/ если что.
http://ideone.com/QpWj9l

Аноним Втр 19 Ноя 2013 20:54:00  #266 №336250 

ОП, это кун который вчера спрашивал тебя про не работающий Апач когда к нему подключаю 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

Аноним Втр 19 Ноя 2013 21:00:47  #267 №336253 

ОП, это кун который вчера спрашивал тебя про не работающий Апач когда к нему подключаю 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

!xnn2uE3AU. Втр 19 Ноя 2013 22:34:29  #268 №336278 

>>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 и покажи нам)

!xnn2uE3AU. Втр 19 Ноя 2013 22:39:02  #269 №336279 

>>336253

Трюки вроде установки на 64-битную систему 64-битного Апача и 32-битного PHP точно не сработают. Все должно быть одинаковой битности (включая библиотеку redistributable от майкрософт).

Аноним Втр 19 Ноя 2013 22:42:57  #270 №336280 

Привет, Анон.
Сперва скажу спасибо, благодаря тебе я устроился джуниором на пхп.
Но у меня проблема, которая заключается в следующем. Есть форма - вводишь данные, нажимаешь сохранить, и программа запихивает все в базу данных. Проблема в том, что после этого, если что-то поменять в инпутах и снова нажать Сохранить, то программа должна обновлять только что созданную запись. Как это лучше сделать?
Я думаю использовать такой вариант: после того, как данные в БД записаны, с помощью LAST_INSERT_ID получить id и сделать редирект на новую вьюшку, передав id. Потом уже извлекать данные, вставлять их в точно такую же форму, но при сабмите обновлять данные. Как думаешь, такое решение пойдет?

!xnn2uE3AU. Втр 19 Ноя 2013 22:58:56  #271 №336287 

>>336246

> никто блджад в этом сраном мануале не потрудился сообщить о том, что функция preg_match_all, если ей передать флаг PREG_OFFSET_CAPTURE будет выдавать смещение в БАЙТАХ а на в символах...

Бывает. Ведь PHP-ники не сами писали обработку регулярок, а подключили библиотеку pcre, видимо на этот момент не обратили внимания.

Для преобразования байты → символы можно применить хак (мы отрезаем кусочек строки в байтах и считаем его длину в символах):

$offsetChars = mb_strlen(substr($string, 0, $offsetBytes));

Вообще, сделано неплохо. Выводится причина ошибки, это хорошо. Жаль, нелегко понять где именно, так как ошибочное место не выделено ни стрелочками, ни скобками, напрмер так:


...жывотное ...


или так:

...→жы←вотное ...
...[жы]вотное ...
..._жы_вотное ...



Баги: http://ideone.com/1XpcDf — глючит когда одна ошибка несколько раз, не видит «этажы» в конце текста, не видит ошибки в «нас 100 а он 1».

Если ты хочешь написать например «цифра или конец текста», можно написать (\\d|\\Z)

\\Z значит конец строки, \\A — начало: http://www.php.net/manual/ru/regexp.reference.escape.php

Советы:

У тебя повторяются куски регулярки: в массиве possibleErrors и в regExp. Это плохо, так как когда правишь, можно забыть поправить в другом месте или сделать это неправильно. Лучше бы автоматом собирать regExp из кусочков, например так:

$reg = '...' . implode(')|(', array_keys($errors)) . '...';

Копипаста — источник ошибок в программах.

> [а-яё]{1}
Можно просто [a-яё]

> $position = (mb_strpos($coolStory, $value) < 20) ? 0 : mb_strpos($coolStory, $value) - 20;

Можно писать max(0, mb_strpos(....) - 20); — функция max не даст взять значение меньше 0

> echo "Ошибка" . $errNo . ":\"...";
Лучше без точек: echo "Ошибка {$errNo}:\"...";

Внутри квадратных скобок обяательно экранировать надо только минус и квадратные скобки, а ? и . можно писать без бекслещей (ну можно и с ними).
!xnn2uE3AU. Втр 19 Ноя 2013 23:02:31  #272 №336288 

>>336280

Да, сделай в форме скрытое поле id. Изначально оно пусто, а после создания записи делай редирект на адрес в котором есть id:

- открываем страницу scrip.php, форма пуста
- отправляем форму через POST, запись вставляется в базу и редиректит на scrip.php?id=12345
- при открытии этой ссылки в форму подставляется id из параметров и пишется текст «Редактирование записи 12345»
- когда ты отправляешь форму, скрипт по наличию id понимает что надо редактировать запись.

Обрати внимание на редикерт после POST. Это нужно чтобы при нажатии F5 не вставилась еще одна запись.

Аноним Втр 19 Ноя 2013 23:16:42  #273 №336290 


>>336288
>Обрати внимание на редикерт после POST. Это нужно чтобы при нажатии F5 не вставилась еще одна запись.
Можно насчет этого поподробней. И еще одно забыл. У меня же есть еще одна кнопка: сохранить и создать новое. Я так понимаю, различить какую кнопку нажал юзер можно только с помощью js, но вот как сабмитить форму при этом я совсем не въезжаю.

!xnn2uE3AU. Втр 19 Ноя 2013 23:20:36  #274 №336292 

>>336290

Если у кнопки есть имя (name =), то вместе с данными формы отправляется параметр с именем нажатой кнопки (попробуй сделать var_dump($_POST) чтобы увидеть).

Но если ты хочешь извратиться делать через JS (например чтобы поддержать ИЕ6 который отправлял все кнопки button а не только нажатую), то тоже нет проблем. При клике на кнопку пишешь в скрытое поле что это за кнопка и делаешь form.submit(), где form — это DOM-нода формы (ее можно получить например getElemetnById()): http://learn.javascript.ru/forms-methods

Аноним Втр 19 Ноя 2013 23:28:08  #275 №336293 

>>336292
Понятно. Спасибо.

Аноним Срд 20 Ноя 2013 00:05:04  #276 №336303 

>>336278
Ура! У меня все заработало, ОП, но я так и не понял в чем была ошибка. Нагуглил туториал вот этот:
http://www.youtube.com/playlist?list=PLV19T7yKWLmZkZl2Ti8fa3g4Sdyd3ZrBp
Поставил в точности такие же версии какие ставит и он, прописал все под диктовку и слава всем богам - завелось. Может я поставил не весь нужный софт, который требовался для новых версий (хотя и со старыми у меня ничего вчера не получалось), может еще что-нибудь. Но скорее всего из-за того что не настраивал файл php.ini, а лишь оставлял его как есть. Это может быть из-за этого? Даже не знал, что что-то нужно прописывать и там.

!xnn2uE3AU. Срд 20 Ноя 2013 00:06:42  #277 №336304 

>>336303

Скорее всего ты опечатался когда прописывал путь к php в конфиге апача.

Аноним Срд 20 Ноя 2013 00:12:20  #278 №336306 

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

Аноним Срд 20 Ноя 2013 11:01:56  #279 №336366 

Похожие посты. Анон, как оно реализуется? Часто на сайтах при чтении статей есть раздел ПохожиеСтатьи. Какая статья похожа на какую - прописывается только вручную или есть какие-то механизмы, основанные на тегах, например? Зачем, кстати, нужны теги, куда их прописывать и что вообще с ними делать?

!xnn2uE3AU. Срд 20 Ноя 2013 13:39:37  #280 №336397 

>>336366

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

> Зачем, кстати, нужны теги, куда их прописывать и что вообще с ними делать?
Если ты не знаешь, зачем они нужны, значит тебе они не нужны. Но вообще теги — это пришло из блогов, это что-то вроде тем, которые затрагивает пост, например:

«Работаем с Yandex Maps API», теги: JS, Yandex maps
«Никому нельзя верить», теги: отношения, печалька, когда это кончится

Потом можно найти все посты с тегом «JS» например. Посмотри например теги под статьями на хабре или в ЖЖ.

Аноним Срд 20 Ноя 2013 16:05:43  #281 №336427 

>>336155
http://ideone.com/cYEFd4
а теперь второй цикл отказывается работать

Аноним Срд 20 Ноя 2013 16:29:21  #282 №336432 

>>336427
http://ideone.com/kFbw80
быстрофикс,вроде работает

Аноним Срд 20 Ноя 2013 16:53:57  #283 №336436 

>>336306
Чому линукс в виртуалку не поставишь? Рабочий LAMP ставится одной командой, и все равно потом это будет работать на линуксе.

Аноним Срд 20 Ноя 2013 17:52:03  #284 №336445 

>>336397
тогда можешь рассказать, как они реализуются? В каком виде хранятся в базе, как происходит поиск по ним (допустим, количество статей, как на хабре или постов, как у жж, у каждого по 3-10 тегов). До черта же информации, поиск должен быть долгим

!xnn2uE3AU. Срд 20 Ноя 2013 18:48:23  #285 №336477 

>>336432

Молодец, правильно работает.

!xnn2uE3AU. Срд 20 Ноя 2013 18:51:50  #286 №336480 

>>336445

Реализуются самым простым образом: таблица tags, где хранятся теги и таблица связи многие-ко-многим tags_to_posts. Для оптимизации (чтобы не джойниться при выводе постов) можно в таблицу постов в отдельном поле засунуть список тегов через запятую, но надо не забывать его обновлять при редактировании.

Поиск идет с помощью SQL-запроса SELECT наверно.

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

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

Аноним Срд 20 Ноя 2013 20:30:20  #287 №336509 

>>335764
>Ну вообще не такой и громоздкий, если подумать.

Я подумал и таки получилось. И правда несложно:
"/^[8\\+7]{1,2}[\\s(-]\\d{3}[\\s)(-](\\d[-)(\\s]?){7}$/"

Это третья задачка на регулярки.

http://ideone.com/ZGLiNh

Аноним Срд 20 Ноя 2013 20:32:10  #288 №336511 

>>336509
блджад не та ссылка http://ideone.com/eHNoCl

!xnn2uE3AU. Срд 20 Ноя 2013 20:36:41  #289 №336513 

>>336509

Пропускает неверный номер: http://ideone.com/CXEkrb
Не пропускает верный: http://ideone.com/oIy5X6

Думаю лучше не задавать жестко 3 цифры в коде города, а разрешить любые 10 цифр + разделители.


Аноним Срд 20 Ноя 2013 20:44:05  #290 №336515 

>>336513
ох ты ж какой молодец, все дыры увидишь, спасибо.

Аноним Срд 20 Ноя 2013 21:17:38  #291 №336521 

>>336513
Пофиксил! Ну теперь-то не придраться, ОПушка.
http://ideone.com/jZZcAZ

!xnn2uE3AU. Срд 20 Ноя 2013 21:49:55  #292 №336527 

>>336521

Теперь все верно.

Аноним Срд 20 Ноя 2013 22:51:15  #293 №336551 

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


!xnn2uE3AU. Срд 20 Ноя 2013 23:13:10  #294 №336555 

>>336551

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

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

Для начала, почитай «Руководство по проектированию реляционных баз данных»: http://habrahabr.ru/post/193380/ желательно целиком.

Там описаны как раз способы связи таблиц, в том числе «многие ко многим».

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

http://xpoint.ru/know-how/MySQL/Optimizatsiya/Indeksyi
http://habrahabr.ru/post/31129/
http://habrahabr.ru/post/70640/

Если в этих статьях что-то непонятно написано, пиши, разберемся.

Аноним Чтв 21 Ноя 2013 06:18:55  #295 №336606 

Сап, Антуаны, заебался искать примеры того, как на ПХП сжимать пачку файлов в файл.tar.bz2
Если не сложно, можно пример чтоб легко понять, что к чему. Файлы будут выбираться из папки по шаблону, я без понятия, как оно работает на ПХП с модулями сжатия, можно ли туда пихнуть массив имён файлов или надо по одному циклом добавлять. И нужно сделать так, что если всё прошло успешно, файлы потереть с папки. Всё что находил было про Phar и ни разу ни одного примера про tar.bz2, я не совсем знаком с вызовом команд из библиотек с "классами"(или как их там).

!xnn2uE3AU. Чтв 21 Ноя 2013 15:52:43  #296 №336712 

>>336606

Тут есть примеры кода: http://www.binarytides.com/how-to-create-tar-archives-in-php/ с Phar. Пример простой.

> я не совсем знаком с вызовом команд из библиотек с "классами"(или как их там).
Ну так изучи ООП. У меня есть первый урок по ООП тут: http://archive-ipq-co.narod.ru/l1/pasta.html

Аноним Чтв 21 Ноя 2013 21:22:54  #297 №336823 

$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 работает и выдает все верно (пикрелейтед)

Аноним Чтв 21 Ноя 2013 22:19:24  #298 №336835 

>>336823

Почитай мануал.
http://us3.php.net/manual/ru/function.mysql-fetch-array.php

fetch_array возвращает 1 ряд за раз, а не весь результат.

Аноним Чтв 21 Ноя 2013 22:54:09  #299 №336841 

>>336835
А что надо, чтобы вернул весь результат?

!xnn2uE3AU. Чтв 21 Ноя 2013 22:55:35  #300 №336842 

>>336841

Использовать цикл while: посмотри на примеры кода в мануале http://php.net/manual/ru/function.mysql-fetch-array.php

Аноним Птн 22 Ноя 2013 14:57:31  #301 №336965 

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

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

Аноним Птн 22 Ноя 2013 15:12:29  #302 №336966 

>>336965
@ тормозит же.
http://ideone.com/zhuX30 — без @
http://ideone.com/BmyVLu — c @

!xnn2uE3AU. Птн 22 Ноя 2013 15:40:12  #303 №336970 

>>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 есть еще пара функций, которые генерируют неотключаемые варнинги даже когда не нужно, но опять же, прежде чем ставить @ стоит посмотреть — может, эту проблему уже поправили?

Аноним Птн 22 Ноя 2013 18:02:38  #304 №336999 

Ололо я теперь гуру регулярных выражений, благодаря Опу.
http://ideone.com/is6Evl
http://ideone.com/bC4xUI
http://ideone.com/kMENMk



!xnn2uE3AU. Птн 22 Ноя 2013 18:39:40  #305 №337004 

>>336999

О, неплохо. Но и тут есть баги.

Первая задача: http://ideone.com/1wFk6A — большие буквы заменяются на маленькие, и вместо $2 написано S2.

Вторая задача: все хорошо сделано.

Третья: все верно, работает.

Аноним Птн 22 Ноя 2013 21:36:13  #306 №337042 

>>337004
ОП-先生! я тебе еще покушать принёс! Отличная задачка, заставила подумать.
http://ideone.com/SZAvQY

!xnn2uE3AU. Птн 22 Ноя 2013 22:39:20  #307 №337059 

>>337042

Боюсь, надо подумать еще. http://ideone.com/u8dvOx — этот текст что-то толком не обрабатывается, пробелы не исправляются.

Аноним Птн 22 Ноя 2013 23:15:39  #308 №337072 

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

Аноним Суб 23 Ноя 2013 00:28:49  #309 №337092 

ОПушка, помоги пожалуйста. У меня ТРУБЫ ГОРЯТ написать электронный дневник, который в последствии будет моей курсовой, а при полнейшей доработке дипломной работой. 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. С меня твердое обещание разобраться как это делается и в будущем самому делать подобные вещи как раз плюнуть.

!xnn2uE3AU. Суб 23 Ноя 2013 00:33:21  #310 №337094 

>>337092

Гугли JOIN, он объединяет таблицы вместе. Алсо поля надо называть нормально, например user_id или id_user, а не через точку. И конечно хорошо бы не транслитом.

!xnn2uE3AU. Суб 23 Ноя 2013 00:35:49  #311 №337095 

>>337092

давно бы выгуглил:

http://www.anton-pribora.ru/articles/mysql/mysql-join
http://www.anton-pribora.ru/articles/mysql/mysql-join

!xnn2uE3AU. Суб 23 Ноя 2013 00:36:51  #312 №337096 

>>337092

Вторая ссылка: http://www.mysql.ru/docs/man/JOIN.html

>>337072

Поможет, тем более что половина геймдева сейчас онлайн-игры делает.

Аноним Суб 23 Ноя 2013 00:39:40  #313 №337099 

Анон, ты советовал мне
>>333180
в ответ на этот пост вот эту либу
>>333191
До сих пор разбираюсь. Всё хорошо, все круто, но есть три больших подводных камня, точнее, два маленьких и один огромный.
1) Все круто, интерфейс хорош, но все это жутко избыточно, мне это все не надо, автоматы это очень здорово, гораздо круче регулярок, но мне нужно всего 5-10 тэгов, а для отключения всего остального надо сильно править исходники.
2) Хреново создаются стили css, все кидается в один класс и разбивается по типам, лучше бы делал отдельные классы с префиксами, а лучше, если бы я сам решал, где класс нужен, а где нет. Но это опять активно править исходники.
3) Третий и главный камень - для решения первых двух первых проблем мне не только не хватит опыта, но мне это делать не позволит лицензия, так как измененный код я опубликовать не могу, проект закрытый. Поэтому вопрос: есть ли что-то подобное, тоже на автоматах, но под MIT, например? Или решающее первые две проблемы. Сам написание вряд ли осилю.

Аноним Суб 23 Ноя 2013 00:49:22  #314 №337102 

>>337096
Окей, бегло окинув статьи понял что JOIN при при использовании селекта образует какую-то третью таблицу, где хранятся данные в которых объединены заданные поля. Я правильно понимаю? Но ведь мне не совсем это нужно. Мне нужно чтобы ввел я в форму допустим логин нового студента, его пароль, выбрал нужный мне месяц, ввел значения прогулов, отправил запрос. В итоге у меня данные в таблицк users добавляется новая строка, где id прописался автоматически, логин записался с отправленных данных, также пароль. В этот же момент, когда внесены в таблицу users необходимые данные, мы в таблицу info колонку users.id добавляем нового студента считанное с таблицы users, в колонке mouths добавляем значение переданное с формы, в колонки пропусков по ув и н/у причине добавляем также значение переданное с формы. Вот и все, добавили в таблицу users нового пользователя, расширили таблицу users и info, прибавив ей нужные значения.
Или я не так что-то понимаю?

Аноним Суб 23 Ноя 2013 01:03:47  #315 №337106 

>>337102
id.Users и id.Months - внешние ключи, но это только позволит контролировать целостность таблиц. Можно обойтись без них.
Добавлять строку в info придется отдельным запросом.

Аноним Суб 23 Ноя 2013 01:24:42  #316 №337114 

>>337106
>id.Users и id.Months - внешние ключи
То есть внешние - значит никак не относящиеся к таблице info? Значит в таблице info нельзя использовать какую-то ссылку на значение определенной строки из другой таблицы? Как же все запутанно.

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

>Добавлять строку в info придется отдельным запросом.
То есть у меня есть форма, куда я ввел информацию о студенте. Ввел его логин, пароль, месяца в который хочу вписать пропуски, все это записалось в какие-то переменные, переменные хранятся в сессии. Далее выполняется первый запрос, а именно запрос на занесение данных в таблицу users. Берем из сессии логин, пароль, добавляем их в таблицу. В итоге у меня в users появился новый пользователь. Далее пошел второй запрос. Второй запрос выбирает id этого последнего пользователя, запоминает в переменную. Пошел третий запрос. В третьем запросе идет вставка уже наконец-то в таблицу info, где поле id вставляется из переменной последнего созданного пользователя, поле id.mouths вставляется тоже из переменной в сессии, поле пропусков тоже из сессии. В итоге чисто теоретически получилась новая запись в таблице info, содержащая параметры которые мне были нужны. А уже селектом я могу использовать этот самый JOIN, объеденяя их и выводя нужную информацию. Это так должно работать? Это и есть связи, или это велосипед говнокодовый? И сам запутался, и вас наверное запутал.

Аноним Суб 23 Ноя 2013 01:42:37  #317 №337120 

аноны, такой вопрос: на локальном сервере установлен apache+mysql+php, создаю папку тестовую папку с данными сайта, помещаю туда index.php, все работает нормально. создаю вторую папку с сайтом, помещаю туда тот же файл-пишет нет прав доступа (в настройках апача и хостов все прописано верно), перемещаю данные второго сайта в папку первого - все работает, значит, если настройки одинаковы для обоих сайтов одинаковы, то дело в настройках апача, может кто-нибудь знает какие конкретно настройки отвечают за количество серверных имен, запускаемых с одной машины?

!xnn2uE3AU. Суб 23 Ноя 2013 01:52:11  #318 №337123 

>>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. Согласен, название дурацкое.

!xnn2uE3AU. Суб 23 Ноя 2013 01:57:21  #319 №337125 

>>337114

> Далее пошел второй запрос. Второй запрос выбирает id этого последнего пользователя, запоминает в переменную.
Погугли насчет функции lastInsertId (например http://php.net/manual/ru/pdo.lastinsertid.php если ты как правильный пацан юзаешь PDO для работы с базой) — чтобы получить id последней вставленной записи есть готовое решение и надо использовать эту функцию, а не лепить велосипеды.

> Это так должно работать? Это и есть связи, или это велосипед говнокодовый?
Если не считать lastinsertId то все верно. Насчет JOIN, ты пока можешь руками вставить записи в базу и потренироваться писать джойны. Но вообще, джойн по сути просто объединяет 2 таблицы декартово (то есть для каждой строки первой таблицы подставляет все строки второй) и потом отсеиивает записи по условиям указанным в ON и WHERE.

!xnn2uE3AU. Суб 23 Ноя 2013 02:00:43  #320 №337128 

>>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) Все же разберись с той библиотекой и научись ее правильно настраивать. Наверняка там все отключается через конфиг.

!xnn2uE3AU. Суб 23 Ноя 2013 02:02:45  #321 №337131 

>>337102

> JOIN при при использовании селекта образует какую-то третью таблицу
Это воображаемая временная таблица, объединяющая сджойненные, которая создается на время SELECT и из которой выбираются данные. Никаких новых постоянных таблиц не создается.

!xnn2uE3AU. Суб 23 Ноя 2013 02:06:10  #322 №337134 

>>337120

По идее каждый сайт описывается отдельно в конфиге апача. Пример: http://easylinux.ru/node/291/

Учти, сейчас в дебиане принято не сваливать настройки сайтов в один файл, а создавать на каждый конфиг в /etc/apache2/sites-available и включать из через a2ensite

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

Аноним Суб 23 Ноя 2013 02:19:59  #323 №337137 

>>337128
регулярки давно освоил, но это убого и есть куча случаев вроде вложенных или неправильных тегов, их регулярки не возьмут.
Хочу автоматы, как в библиотеке. Пару тредов назад ты пилил здесь мануалы про рекурсивные парсеры, это оно и есть? Я совсем не шарю в этих парсерах, автоматах... есть хорошие статьи по теории? Еще про парсер xml и сборку xml в PHP почти ничего не знаю, как-то было в книжке непонятно написано, я и плюнул. Видимо, зря. Базовые вещи типа того, что такое рекурсия и как ей считать факториал знаю, лол.

Аноним Суб 23 Ноя 2013 02:21:08  #324 №337138 

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

Аноним Суб 23 Ноя 2013 02:23:14  #325 №337139 

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

!xnn2uE3AU. Суб 23 Ноя 2013 02:36:12  #326 №337140 

>>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!"


Ну а из дерева уже нетрудно сгенерировать HTML.
!xnn2uE3AU. Суб 23 Ноя 2013 02:42:30  #327 №337141 

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

Аноним Суб 23 Ноя 2013 11:48:23  #328 №337170 

>>337141
с этим понятно, спасибо,
а вот это
>>337140
понял совсем плохо. По каким тегам гуглить и какая это вообще теория, лол? Так и гуглить: "как сделать парсер на php" и "как сделать дерево на php"?

Аноним Суб 23 Ноя 2013 12:14:57  #329 №337173 

>>337059
http://ideone.com/WRHpta PCRE is my bitch.

Аноним Суб 23 Ноя 2013 13:09:49  #330 №337180 

>>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 все в порядке.

Аноним Суб 23 Ноя 2013 13:34:50  #331 №337183 

http://ideone.com/VGOSQ8

Оп, а почему когда я попытался написать вместо array_reverse shuffle, выдало не совсем то чего ожидал...

Аноним Суб 23 Ноя 2013 14:30:56  #332 №337190 

>>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.

Аноним Суб 23 Ноя 2013 15:18:30  #333 №337197 

Пыханы пришла вот такая параша в задании на собеседование
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=
Чего делать с этим говном или это заебанная кодировка? Я спрашивал про технические проблемы но тня пм ответила что все должно отображаться норм и я подумал что это говно часть задания. В файле не было никаких инструкций только надпись задание и выложенная выше абракадабра
Претендую на начинающую веб-макаку но с этим не сталкивался, что это вообще?

Аноним Суб 23 Ноя 2013 15:30:17  #334 №337200 

>>337197
на какую должность собеседование?

Аноним Суб 23 Ноя 2013 15:33:55  #335 №337201 

>>337200
джун конечно
еще дали написать бинарный поиск с изъебом и сумму подмассива но там легко

Аноним Суб 23 Ноя 2013 15:37:56  #336 №337202 

>>337197
Это список тестовых заданий тебе, дан он в кодировке base64.
Декодится здесь: http://base64.ru/
А вообще они охуели. Небось мухосранск с небольшим количеством фирм и большим числом никому ненужных быдлокодеров.

Аноним Суб 23 Ноя 2013 15:42:22  #337 №337205 

>>337202
спасибо бро
да не, я им сказал что студентота и что у нас учат хую корявому
Сказали что рук не хватает вообще

Аноним Суб 23 Ноя 2013 15:48:25  #338 №337207 

>>337205
>Сказали что рук не хватает вообще
Пиздят. Такие задания и в такой форме дают только те кому новые работники нахуй не нужны. Я бы даже не стал делать это всё, сразу бы нахуй их послал. Честно говоря, само такое задание выглядит как посыл на хуй, и не факт что после того как ты его сделаешь они тебя возьмут. Это больше похоже на прикол. Они бы еще AES'ом зашифровали 128-битным ключом.

Аноним Суб 23 Ноя 2013 15:50:29  #339 №337208 

>>337197

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

http://ru.wikipedia.org/wiki/Обфускация
http://habrahabr.ru/post/137459/

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

№337200-кун

Аноним Суб 23 Ноя 2013 15:55:04  #340 №337209 

>>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.
Вот это на алгоритмы

Аноним Суб 23 Ноя 2013 15:59:26  #341 №337211 

>>337209
Точно, ты прав, я встречал такую хрень когда разбирался с цифровыми подписями и формированием хml отчетов через php скрипты, и первым делом подумал в ту сторону, спасибо за задания

Аноним Суб 23 Ноя 2013 16:01:17  #342 №337212 

>>337211
алсо как ты видишь они не совсем сложные, ну первое точно
по второму можешь глянуть этот линк и поймешь
http://forum.xakep.ru/m_1238569/tm.htm

Аноним Суб 23 Ноя 2013 16:16:27  #343 №337214 

>>337202
>Небось мухосранск с небольшим количеством фирм и большим числом никому ненужных быдлокодеров.
Лол, как я угадал.
Фирма из Новокузнецка оказалась.

Аноним Суб 23 Ноя 2013 16:24:06  #344 №337215 

>>337214
А ты раньше встречал эту кодировку? я к тому как ты догадался, что это зашифрованный текст именно в base64

Аноним Суб 23 Ноя 2013 17:17:50  #345 №337223 

вавп

Аноним Суб 23 Ноя 2013 17:21:30  #346 №337225 

>>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.

И да, это сообщение никто из наших сходу не расшифровал, а более глубоко скорее всего никто и не брался, а если и брался, то втихую зафейлил.

Аноним Суб 23 Ноя 2013 17:27:02  #347 №337227 

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

PS
Пиздец. Даже это сообщение отправить не удалось и пришлось в слове t.cо букву о делать русской. Ну полный пиздец. Аноны, как вы тут двачуете вообще? Несколько месяцев меня здесь не было и такой пиздец стал.

Аноним Суб 23 Ноя 2013 18:07:41  #348 №337234 

>>337225
>Mj Bj Qk
Скорее всего веб-дебильчики зашифровали текст каким-нибудь убогим Виженером. Попробуй ебнуть по тексту вероятностным криптоанализом, а то я свою библиотеку для частотного анализа проебал.

Аноним Суб 23 Ноя 2013 18:16:23  #349 №337235 

>>337234
Частотный анализ соснет и это очевидно в общем-то, если присмотреться к тексту. Я тогда в скайпе написал:
>Mj похоже левая инфа, типа какого-то префикса или команды, дальше идет параметр A или B, после которого еще один параметр.
Этими Mj текст нашпигован, ни один человеческий язык такой херни не имеет. Так что это похоже какие-то данные, которые хитровыебано закодированы алгоритмом очень похожим на сжатие, правда сжимающим хуёво, возможно и не сжимающим вовсе, но по виду он как сжатие.
Там еще был какой-то ключ шифрования в тексте сообщения на русском, которое сопустствовало этой кодированной херне. Гуглится легко теперь уже.

!xnn2uE3AU. Суб 23 Ноя 2013 18:21:12  #350 №337237 

>>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 видов:

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

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

!xnn2uE3AU. Суб 23 Ноя 2013 18:38:38  #351 №337238 

>>337173

О, хорошо, теперь все правильно. Я тебе советую еще глянуть вот этот раздел: http://www.php.net/manual/ru/regexp.reference.unicode.php

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

!xnn2uE3AU. Суб 23 Ноя 2013 18:40:16  #352 №337240 

>>337183

$wordsR = shuffle($words[$i]);

shuffle не возвращает новый массив, а перемешивает тот, который ей дан. Надо писать ппросто

shuffle($array)

В манауле, кстати это написано: http://php.net/manual/ru/function.shuffle.php в разделе возвращаемые значения.

!xnn2uE3AU. Суб 23 Ноя 2013 18:44:54  #353 №337241 

>>337190

На самом деле, там конфиги объединяются в один и можно писать где угодно.

>>337197

Ну base64 — легко узнать, если ты серьезно изучаешь веб-кодинг, ты с ней столкнешься, например ей кодируются файлы в ссылках data:, заголовки MIME, некоторые клоуны ей кодируют параметры в адресной строке, и наверно еще что-то.

Но задание маленько заморочное, конечно, создавать виртуалку, настраивать, это минимум минут 20-30 уйдет.

Аноним Суб 23 Ноя 2013 18:51:03  #354 №337243 

>>337140
Не забудьте пропарсить вещи вида:
<a>text</b>text<b>text</a>text</b><b>

!xnn2uE3AU. Суб 23 Ноя 2013 18:56:23  #355 №337245 

>>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+


Всего групп 49 (буквы + ?). Та штука, которая встречается 25 раз, наверно пробел или разделитель какой-то.
!xnn2uE3AU. Суб 23 Ноя 2013 19:00:26  #356 №337247 

>>337245

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

Аноним Суб 23 Ноя 2013 23:34:43  #357 №337267 

Слона всем, как учесть летнее/зимнее время? К примеру летом сдвиг по временному поясу -7 а зимой -8 делать?

Аноним Вск 24 Ноя 2013 00:03:16  #358 №337269 

>>337267
отменяется вопрос, забыл про date('I')

Аноним Вск 24 Ноя 2013 03:18:19  #359 №337281 

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

!xnn2uE3AU. Вск 24 Ноя 2013 03:19:55  #360 №337282 

>>337281

У базы и у таблиц должно быть выставлено utf-8. Также, когда коннектишься к базе задай кодировку соединения, выполнив запрос

SET NAMES utf8


!xnn2uE3AU. Вск 24 Ноя 2013 03:21:04  #361 №337283 

>>337281

У базы и у таблиц должно быть выставлено utf-8. Также, когда коннектишься к базе задай кодировку соединения, выполнив запрос.

SET NAMES utf8

Алсо, пароли хорошо бы солить и хешировать.

Аноним Вск 24 Ноя 2013 03:34:07  #362 №337284 

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

Аноним Вск 24 Ноя 2013 06:49:13  #363 №337289 

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

Аноним Вск 24 Ноя 2013 13:48:21  #364 №337308 

ОП, у меня снова подоспел вопрос. Допустим у меня есть вот такая форма:
<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 передавалось значение выбранной группы из выпадающего меню? Либо гуглю плохо, либо никак такое не сделать. Варианты реализации нагуглил только с помощью вынески выпадающего меню в другую форму, и при нажатии на нужную группу сразу передать ее в переменную.

Аноним Вск 24 Ноя 2013 14:09:47  #365 №337312 

>>337308
Туплю, туплю. Уже нашел.

Аноним Вск 24 Ноя 2013 14:49:08  #366 №337320 

>>337240
>shuffle не возвращает новый массив, а перемешивает тот, который ей дан

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

BTW Ну и хардкорная же задачка про числа прописью!

http://ideone.com/0D1E4M

!xnn2uE3AU. Вск 24 Ноя 2013 15:52:06  #367 №337335 

>>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 еще малораспространен, придется тебе ручками солить пароли.

!xnn2uE3AU. Вск 24 Ноя 2013 15:57:23  #368 №337337 

>>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 → ??? не могу придумать

!xnn2uE3AU. Вск 24 Ноя 2013 15:58:35  #369 №337338 

>>337289

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

!xnn2uE3AU. Вск 24 Ноя 2013 16:19:31  #370 №337356 

>>337320

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

Тем более, что у тебя там код какой-то запутанный.

Конечно, тут еще есть хитрый хак, использовать explode(',', number_format($number)), но я думаю, лучше все же обойтись математикой.

А так, программа работает правильно.

Аноним Вск 24 Ноя 2013 18:27:19  #371 №337404 

>>337356
>Разбить число на группы по 3 можно, например, деля его на 1000 и округляя, пока оно не станет равно 0.

Вот до этого не додумался, вот и начал со строкой изъёбываться. Да что там говорить для меня и это вот
$lastTwoDigits = $number % 100

было откровением. Я такой когда это увидел, сказал "Ого-го".

!xnn2uE3AU. Вск 24 Ноя 2013 18:30:56  #372 №337406 

>>337404

По моему, у меня это где-то было написано. Хотя сейчас не помню уже где. Может, под спойлером.

!xnn2uE3AU. Вск 24 Ноя 2013 18:32:20  #373 №337408 

>>337404

А, нашел. В самом первом уроке написано же, ай-я-яй, я так и знал, что половину информации забывают сразу после прочтения.

Аноним Вск 24 Ноя 2013 19:33:05  #374 №337427 

>>333445
Сап, ОП. Проясни одну вещь. Вот есть у меня страница на ПХП. При открытии страницы в браузере отображается .php расширение в конце адресной строки. Чтобы его убрать, надо отредактировать htaccess. Помнится в вордпрессе URL любой страницы окончивался .html расширением. Это тоже редактируется в htaccess по сути? И ещё кое-что: вот есть несколько статей на сайте, доступ к которым осуществляется через GET-метод. URL имеет вид: название_страницы.php?id=666. Произвольные URL для каждой статьи (например чтобы было site_name.ru/articles/chitaemoe-nazvanie.html) настраиваются тоже через htaccess?

Аноним Вск 24 Ноя 2013 19:45:53  #375 №337432 

>>337427
Нашёл.

!xnn2uE3AU. Вск 24 Ноя 2013 20:34:23  #376 №337448 

>>337427

Если правильнее говорить, то не только через htaccess, можно еще например через конфиг Апача. Да, это надо гуглить mod_rewrite — суть в том, что можно все URL, которые не соответствуют файлам на диске, перенаправлять на index.php и там уже анализировать средствами PHP.

> URL имеет вид: название_страницы.php?id=666
Отстойно, надо исправлять, а то поисковики не любят такие адреса.

Аноним Вск 24 Ноя 2013 21:16:01  #377 №337458 

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

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

Второе, более реальная проблема, есть один сайт, который пока не оч нагружен, но разрабатывался с учетом на высокую нагрузку, там очень много обращений к базе на главной, много картинок и js скриптов, все было оптимизировано и сайт грузился за пару секунд все это время, но неожиданно, пару дней назад стал дико тормозить, буквально до полторы минуты, при том, что потребляемый объем памяти и числа процессов на сервере не превышен, хоть и тоже скакнул. Людей там еще немного, во всяком случая пика посещаемости не наблюдалось. Прямо магия какая-то, сижу и не могу понять в чем дело.
Смотрел статистику получения данных в консоли хрома и там тоже сплошная магия, например один файл стилей весом 67кб получен в течении 83ms а другой в 6кб уже за 3.6s(секунд!), при этом все это время 3.6s описано как Waiting (я так и не понял чего он ждал). Далее иногда сайт грузиться в момент, а потом снова часами, хер пойми в чем дело, поясните по хардкору

Аноним Вск 24 Ноя 2013 21:28:31  #378 №337461 

>>337458
не хватает памяти и оно начинает работать через своп. Либо запускается сборщик мусора.
Попробуй поиграться с настройками веб-сервера и субд

мимоджавист

!xnn2uE3AU. Вск 24 Ноя 2013 22:35:06  #379 №337486 

>>337458

> описано как Waiting (я так и не понял чего он ждал).
Ответа со стороны сервера.

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

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

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

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

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

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

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

Для оптимизации запросов надо научиться пользоваться командой EXPLAIN. Статьи ищи в гугле по фразе «MySQL EXPLAIN индексы», просто бери и читай все что там написано.

Для оптимизации PHP-кода можно использовать профайлер, например, расширение xDebug. Он может померять время и число вызовов каждой функции в твоем скрипте и увидеть, где проблемы. Просматривать результаты профайлера можно программой WinCacheGrind или веб-приложением WebCacheGrind (ставится на сервер, работает в браузере).

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

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

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

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

Поставь на сервер оп-кешер, например, XCache. Он экономит время компиляции PHP-кода.

Для тестирования сайта под нагрузкой, научись использовать ab (apache benchmark) или siege. Ты увидишь, сколько пользователей одновременно держит сайт.

!xnn2uE3AU. Вск 24 Ноя 2013 22:36:57  #380 №337487 

>>337458

Еще, кстати, освой команды линукса, такие как htop, iotop, iftop. Они позволяют увидеть, например, хватает ли памяти, хватает ли процессора, большая ли нагрузка на диск и сеть и какая зараза ее создает. Хорошо, например, запустить ab потоков так в 50 и смотреть, как реагирует сервер.

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

!xnn2uE3AU. Вск 24 Ноя 2013 22:38:03  #381 №337488 

>>337461

В Апаче вроде нет сборщика мусора, он на Си, а СУБД для отдачи статических файлов не нужна. А насчет настроек, автор вопроса скорее всего на шаредном хостинге и прав на их изменение у него нету.

Аноним Вск 24 Ноя 2013 23:18:44  #382 №337495 

ОП, проблема на пикрелейтед. Как сделать, чтобы подсветка синтаксиса была корректной?

Аноним Пнд 25 Ноя 2013 09:38:45  #383 №337556 

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

!xnn2uE3AU. Пнд 25 Ноя 2013 11:10:28  #384 №337567 

>>337495

В heredoc маркер конца текста должен стоять в начале строки, без пробелов перед ним. Пример:


$text = <<<EOT
lalala
lalala
EOT; ← нет пробелов и других символов, кроме разве что точки с запятой

Аноним Пнд 25 Ноя 2013 14:03:43  #385 №337599 

Пхп-кун, ответь на мой пост, пожалуйста.

Делаю небольшую программку: вводятся числа, некоторые данные считаются, все это заносится в шаблон rtf и так далее.
У меня такой вопрос: как лучше хранить эти самые числа. На данный момент у меня есть два списка: первый хранит названия для полей ввода (делаю в tkinter'e) а второй список, где собственно хранятся сами числа делается генератором по всем этим названиям, то бишь чтобы добавить новый элемент достаточно вписать в первый массив название. Так вот. Так норм или есть другие общепринятые методы? Потому что в шаблон я вставляю именованными элементами (например %(age)d) и приходится вручную сопоставлять элементы массива конкретному имени. Вот такая простыня.

!xnn2uE3AU. Пнд 25 Ноя 2013 14:45:59  #386 №337610 

>>337599

Я плохо честно говоря понял, о чем речь (какая-то GUI программа?), если речь о том, что поля формы в диалоге нужно периодически добавлять или менять, можно хранить информацию о них в файле, например XML или JSON — для работы с ними есть готовые библиотеки на многих языках.

> Потому что в шаблон я вставляю именованными элементами (например %(age)d) и приходится вручную сопоставлять элементы массива конкретному имени
Ну если я правильно тебя понял, то можно просто автоматически как-то парсить шаблон и извлекать из него все имена, тогда сопоставлять вручную не надо будет.

Аноним Пнд 25 Ноя 2013 15:21:21  #387 №337619 

>>337610
Спасибо, посмотрю и твой вариант.

Аноним Пнд 25 Ноя 2013 16:15:19  #388 №337628 

ОП-кун, вот калькулятор:

http://ideone.com/T4r0x5
В подсказки ни разу не заглянул ни к одной задаче, я могу считать себя программистом 2 lvl? :3.

Аноним Пнд 25 Ноя 2013 16:21:49  #389 №337631 

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

Аноним Пнд 25 Ноя 2013 17:21:33  #390 №337648 

>>337631 пока сунул их в файл рядышком и тащу file_get_contents, но это нубство какое то, хочу в код запихнуть, может закодировать его как то? Или просто заменить "\" на "@@@huy@@@"...

Аноним Пнд 25 Ноя 2013 17:32:41  #391 №337650 

>>337648
Сколько тысячь запросов в секунду обрабатываете?

Аноним Пнд 25 Ноя 2013 18:04:49  #392 №337655 

>>337650
>тысячь запросов в секунду
В среднем примерно столько: 1.6666666666666666666666666666667e-5
Решил уже >>337631 с помощью rawurldecode

!xnn2uE3AU. Пнд 25 Ноя 2013 19:57:52  #393 №337675 

>>337631

Я не понял, в чем проблема с обратными слешами? База данных их позволяет хранить. Ничего специально делать не надо.

!xnn2uE3AU. Пнд 25 Ноя 2013 20:03:31  #394 №337677 

>>337628

В регулярках внутри квадратных скобок [ .. ] надо экранировать только [ ] ^ - , знаки * / + = можно не экранировать (можно и экранировать, хуже не будет).

> else
> echo "Wrong input!"
> exit

Фигурные скобки где? если их не ставить, то к else относится только первая команда и такой код равносилен

else {
echo ....
}

exit

То есть exit оказывается за пределами else, а не в нем. Потому не надо пропускать фигурные скобки.

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

!xnn2uE3AU. Пнд 25 Ноя 2013 20:08:05  #395 №337679 

>>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.

Аноним Пнд 25 Ноя 2013 21:11:57  #396 №337702 

>>337677
оу оу оу полегче, ОПчик. В начале этого урока сказано, что кто решит задачи из этого урока, тот получает второй лвл. Нет, следующие-то я тоже конечно решу, и добавки еще попрошу, но 2й лвл то я уже щас хотел апнуть!
Насчет экранирования - знаю, ты говорил уже, но почему-то именно в этой задаче если их убрать, ничего не работает.
Говорит что-то типа undefined modifier, как будто не видит что всё это в квадратных скобках, я не знаю почему так.
а по поводу скобок фигурных, да косяк. Просто ехit я потом дописал, а скобки не добавил по невнимательности.

!xnn2uE3AU. Пнд 25 Ноя 2013 21:22:58  #397 №337709 

>>337702

> Говорит что-то типа undefined modifier, как будто не видит что всё это в квадратных скобках, я не знаю почему так.
Это потому что неэкранированный знак деления он принимает за конец регулярки, она же у тебя в слеши заключена и офигевает от того что там куча непонятных флагов идет после слеша.

> но 2й лвл то я уже щас хотел апнуть!
Ну тут такая история. Раньше калькулятор был последней задачей в учебнике. Так что апнуть ты можешь. Но учти, это не все, там еще задачи есть и есть ООП, который еще за поллевела считается.

Аноним Пнд 25 Ноя 2013 23:19:59  #398 №337722 

А что, в пыхе нет моей любимой конструкции с сокращенным циклом И, ИЛИ?
var $переменная = $значение || $дефолт
Не хотеть ифы, функции и тернаропроблемы, у меня VOCAROO от этого

Аноним Втр 26 Ноя 2013 00:46:49  #399 №337737 

ОП запили мне про жизнь объектов, кеширование (не nginx а в функциях), хорошие практики.
inb4: на сайте не нашел.

Аноним Втр 26 Ноя 2013 00:48:05  #400 №337738 

>>337737
ну и про оптимизации забыл еще.

Аноним Втр 26 Ноя 2013 09:37:47  #401 №337774 

>>337722
Операция есть, но результат ее - булево значение, а не один из параметров, так что обломись.
Можешь использовать
var $переменная = $значение ?: $дефолт;

!xnn2uE3AU. Втр 26 Ноя 2013 14:09:29  #402 №337799 

>>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 — надо сбросить кеш, юзеру подарили подарок — надо сбросить кеш числа подарков, отправили сообщение — надо сбросить счетчик числа сообщений, и так далее.

В чем еще подвох? Кеш — не база данных. Он может сброситься в любой момент и нельзя хранить в нем данные.

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

Аноним Втр 26 Ноя 2013 14:28:57  #403 №337805 

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

Аноним Втр 26 Ноя 2013 14:31:18  #404 №337807 

>>337805
> кешировать на уровне записей из БД
подробнее если можно.
Хотет хорошо вникнуть в пхп, не просто хорошо писать код пользуясь встроенными функциями но и понимать какие лучше и что за ними происходит.

!xnn2uE3AU. Втр 26 Ноя 2013 14:38:53  #405 №337813 

>>337805

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

Там есть 2 системы: счетчик ссылок (уничтожает объекты без кольцевых ссылок) и сборщик мусора (уничтожает любые объекты). Описание есть в мануале: http://php.net/manual/ru/features.gc.php

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

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

!xnn2uE3AU. Втр 26 Ноя 2013 14:41:24  #406 №337814 

>>337807

> подробнее если можно.
Ты с мемкешем работал? Если нет, поищи например где-нибудь на хабре статью про него и начни с теории. Просто иначе ты все равно ничего не поймешь.

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

Аноним Втр 26 Ноя 2013 14:44:55  #407 №337815 

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

!xnn2uE3AU. Втр 26 Ноя 2013 14:54:53  #408 №337816 

>>337815

> Соответственно, прежде чем сохранить экранированный sql в пхп его нужно еще раз заэкранировать (\\\\\\\\)
Если ты используешь PDO и плейсхолдеры оно все само экранируется. Если ты используешь mysql_* ты и так наверно привык писать везде mysql_real_escape_string, так что не вижу никакой разницы: что сохранить в базе комментарий в котором могут быть теги, кавычки и слеши, что регулярку.

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

Аноним Втр 26 Ноя 2013 15:26:56  #409 №337823 

>>337816
>лучше в закодированном виде хранить в пхп файле

GTO - great teacher OP Аноним Втр 26 Ноя 2013 16:53:12  #410 №337838 

Я ещё одну решил, Опчик.

http://ideone.com/v4ywrg

Аноним Втр 26 Ноя 2013 18:17:41  #411 №337849 

ОП, у меня к тебе серьезный вопрос насчет выбора языка.
Мотивацией для меня стало написание своего первого сайта, ввиду большой распространенности выбрал пхп, но смущает большое количество негативных отзывов об этом языке. К тому же, насколько я понимаю, большинство скриптов современных сайтов выполнено на явескрипт.
В связи с этим вопрос: верен ли выбор пхп как первого вэб языка? или стоит предпочесть ему явускрипт(питон).
И еще такой вопрос: для сождания сайта использую apach+sql+php, будет ли эта же конструкция работать, если заменить php на js(соответственно переконфигурировать апач)? Заранее спасибо

!xnn2uE3AU. Втр 26 Ноя 2013 18:29:38  #412 №337851 

>>337849

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

Конечно, есть такая штука как node.js, которая запускает яваскрипт на сервере, но не думаю, что начинающему ее будет просто понять.

> для сождания сайта использую apach+sql+php, будет ли эта же конструкция работать, если заменить php на js(соответственно переконфигурировать апач
Нет. Чтобы выполнять JS на сервере, надо Node.JS а не апач.

> но смущает большое количество негативных отзывов об этом языке
А ты не читай отзывы несчастных ява-кодеров в /pr. Ты открой сайт с работой, например hh.ru или hantim.ru и посмотри число вакансий по разным языкам.

Питон — неплохой язык, но по моему он менее распространен и чуть посложнее PHP.

!xnn2uE3AU. Втр 26 Ноя 2013 18:45:09  #413 №337858 

>>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р, этот алгоритм не сработает).

Аноним Втр 26 Ноя 2013 20:58:39  #414 №337896 

Дичайше плавится мозг от вроде бы простой задачки. Допустим, нужно реализовать механизм акции для какого-нибудь магазина. Менеджер в админке указывает дату начала и дату конца, а также условие, например скидка 10% от цен на определенную категорию товаров, например бухло. Т.е., допустим, 01.02.2013 один скрипт должен самозапуститься, пробежаться по базе и поправить цены. Другой скрипт, допустим 01.03.2013 все откатить обратно. Нагуглил про cron, но не вижу как он тут может помочь, скрипты-то не руками должны добавляться в админке хостинга, а в скрипте.
Приходит в голову такое решение - добавить в cron скрипт, который ежедневно проверяет таблицу 'акции' в базе. Если сегодня=дата начала/конца - выковырять из поля сделать скидку/вернуть как было текст внутренних скриптов, запустить. Звучит ужасающе. Все правильно придумал?

Аноним Втр 26 Ноя 2013 21:04:57  #415 №337897 

>>337896
>пробежаться по базе и поправить цены
Когда ж вы все передохнете уже наконец, а?

Аноним Втр 26 Ноя 2013 21:47:38  #416 №337907 

>>337851
>Питон — неплохой язык, но по моему он менее распространен и чуть посложнее PHP.
А что насчет Ruby/Rails

!xnn2uE3AU. Втр 26 Ноя 2013 22:10:12  #417 №337915 

>>337907

Тоже неплохой язык. Но там порог вхождения выше, чем в PHP.

>>337896

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

А хранить скрипты в базе — быдлкодинг-стайл.

Аноним Втр 26 Ноя 2013 22:36:26  #418 №337928 

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

Аноним Втр 26 Ноя 2013 23:55:27  #419 №337956 

>>337915
>чтобы он при выводе страницы и в корзине как-то учитывал скидку. Например, проверял, подпадает ли товар под какую-то акцию, если так то скидка
Хм, разве не логичнее один раз запустить примитивное "UPDATE товары SET цена=цена*0.9 WHERE категория=алкоголь", нежели абсолютно любой заказ проверять на текущие акции, которых вообще может и не быть?
>А хранить скрипты в базе — быдлкодинг-стайл.
Ну в принципе это можно и обойти и хранить в базе условия(скидка, категория), а скрипт на ходу составлять из них.
>>337928
>используй эту таблицу для своего петушения. Править он блядь собрался скриптом каждый день.
Почитай внимательно - не править, а проверять нет ли сегодня начала или конца каких-то акций. Если начало - да, править, если конец - откатить и удалить эту акцию вообще. О каком петушении ты говоришь?

Аноним Срд 27 Ноя 2013 00:24:18  #420 №337958 

>>335464
>>335456
Попробовал слегка допилить всё это дело. Убрал правила для пароля и логина, оставил только максимальную длинну имени и минимальную - пароля. Немного переделал отображения, теперь введенные данные не пропадают при повторном выводе формы, если я в первый раз неправильно заполнил каие-то поля. Добавил капчу, отображается при создании постов/комментариев для анонимных пользователей и после некольких зафейленых попыток авторизироваться. Капчу делал сам, нужно будет на ещё доделать, либо взять уже готовый сервис типа reCaptcha.
Добавил поля с csrf-токенами к формам. Разлогин сделал через POST, вроде читал, что не рекомендуют передавать токены через GET.
Ещё добавил поле c 'honeypot captcha', прочитал про неё где-то на хабре, что скажешь, юзать этот метод имеет смысл?
Ну и на всё это у меня ушло реально дохуя времени, нужно будет както величивать работоспособность.

Аноним Срд 27 Ноя 2013 00:29:18  #421 №337959 

>>337958
Ебать я ошибок наделал. Нужно идти спать.

Аноним Срд 27 Ноя 2013 01:23:01  #422 №337966 

>>337956
>Почитай внимательно
>01.02.2013 один скрипт должен самозапуститься, пробежаться по базе и поправить цены
Все написано вполне однозначно.
>UPDATE товары SET цена=цена*0.9 WHERE категория=алкоголь
Править подобным образом - глупость.
>нежели абсолютно любой заказ проверять на текущие акции, которых вообще может и не быть?
Никаких проблем с этим быть не должно. Сомневаюсь, что у тебя сотни запросов в секунду будут, чтобы думать об оптимизации, тем более такой топорной. Профиты очевидны - акции обновляются автоматически, легко редактируются и удаляются, сохраняются первоначальные данные, чтобы не проебаться со стоимостью товара, что может быть критично.

!xnn2uE3AU. Срд 27 Ноя 2013 01:24:33  #423 №337967 

>>337966

Профит в том что иногда надо написать 2 цены например

1000 (зачеркнуто) 900 — скидка 10% на X в этом месяце!

Аноним Срд 27 Ноя 2013 02:30:00  #424 №337971 

Хочу изучить программирование (и устроиться работать кодером! и съебать в таиланд!), но боюсь обнаружить что я непригоден для этого из-за гуманитарности/тупости и что придется похоронить мечту работать по профессии программиста вместо грузчика/кассира.
Что делать, посоны?

Аноним Срд 27 Ноя 2013 03:16:14  #425 №337974 

>>337851
Node это не сервер, это среда выполнения

Аноним Срд 27 Ноя 2013 03:26:12  #426 №337975 

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

Аноним Срд 27 Ноя 2013 04:06:31  #427 №337978 

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

Аноним Срд 27 Ноя 2013 06:57:19  #428 №337982 

>>337971
Не слушай эту тряпку >>337978, анон.

Аноним Срд 27 Ноя 2013 08:12:23  #429 №337985 

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

!xnn2uE3AU. Срд 27 Ноя 2013 10:19:46  #430 №337994 

>>337985

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

Аноним Срд 27 Ноя 2013 11:11:11  #431 №338003 

на сайте в разделе "строки" дошел до задачи "на словах ты лев толстой", бла идея заморочиться и решить ее через массивы(создать массив с маской из позиций требуемых слов, прогнать через него все пять массивов, полученные данные собрать в переменную, а потом ее вывести), но подумал что это слишком громоздко и тупо вывел через echo {$word1[2]} {$word2[4]} и т.д. ОП, не подскажешь какое решение наиболее верно? Выбрал второе исходя из быстродействия: то что содержит меньше команд быстрее выполняется

!xnn2uE3AU. Срд 27 Ноя 2013 11:35:41  #432 №338009 

>>337958

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

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

> Ещё добавил поле c 'honeypot captcha', прочитал про неё где-то на хабре, что скажешь, юзать этот метод имеет смысл?
Имеет. Помогает против тупых ботов, которые не понимают CSS, а просто извлекают форму из HTML-кода и заполняют ее спамом. Я как-то применял на одном сайте именно против таких ботов (они не ориентируются на какой-то один сайт, а просто обходят подряд например миллион самых посещаемых сайтов).

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

Еще важный момент: помни что юзер может открыть несколько вкладок сайта и все они используют общие куки и общую сессию. В частности: открывается первая вкладка, генерируется код капчи в сессии, отображается капча допустим 12345. Открывается вторая вкладка, генерируется новая строка капчи (89098), старая строка в сессии затирается и не сработает.

Чтобы этого избежать, делают так: для каждой капчи генерируют уникальный captcha_key, и хранят данные для каждой капчи отдельно: $_SESSION['captchas']['sdgyadyadtf'] = 12345; Ну и конечно надо периодически чистить массив если там накопилось много капч.

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

!xnn2uE3AU. Срд 27 Ноя 2013 11:36:42  #433 №338010 

>>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).

!xnn2uE3AU. Срд 27 Ноя 2013 11:37:59  #434 №338011 

>>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();
Эти объекты лучше не создавать в вью, а передавать откуда-нибудь. Например, из базового контроллера (так что они будут присутствовать в любом вью).

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

!xnn2uE3AU. Срд 27 Ноя 2013 11:43:31  #435 №338013 

>>337958

> <img src='<?=Config::getBasePath()?>/captcha/create' />

/ в конце тега не нужен.

Адрес картинки плохой, так как он всегда постоянный. Браузеры или прокси могут легко закешировать такую картинку даже если ты выставишь запрещающие заголовки. Лучше добавить в путь уникальные символы вроде /captcha/create/f67fsd7sr (можно использовать captcha_key если он есть)

!xnn2uE3AU. Срд 27 Ноя 2013 12:17:18  #436 №338018 

>>338003

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

Аноним Срд 27 Ноя 2013 12:48:03  #437 №338021 

меня немного вымораживает, когда при форматировании кода по ссылке в оп посте мы получаем

if ($domain == "sait.ru") {
print "Disallow: /zapis.php
";
}

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

!xnn2uE3AU. Срд 27 Ноя 2013 12:52:30  #438 №338023 

>>338021

Может у тебя какие-то символы в строке были? Я попробовал сейчас вставить код

<?php

if ($domain == "sait.ru") {
print "Disallow: /zapis.php";
}

(без отступов), он просто добавил отступ перед print и все. Содержимое строки он по идее трогать не должен.

Единственное, ; переносится если она лишняя. Например, тут:

if (...) {
...
};

; после скобки перенесется на новую строку так как она не нужна.

Аноним Срд 27 Ноя 2013 13:03:50  #439 №338024 

и почему при форматировании первого 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";
}

}

!xnn2uE3AU. Срд 27 Ноя 2013 13:10:32  #440 №338025 

>>338024

Ты маркер <?php перед кодом не забыл поставить? Если поставить, то все как надо форматируется.

Аноним Срд 27 Ноя 2013 13:14:03  #441 №338027 

>>338025
действительно, помогло. интрига.

Аноним Срд 27 Ноя 2013 13:21:51  #442 №338031 

>>337896
У нас вот так зделоли.
Запросы присылать или сам напишеш сам напишит

Аноним Срд 27 Ноя 2013 15:01:13  #443 №338048 

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

Аноним Срд 27 Ноя 2013 17:37:34  #444 №338074 

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

Аноним Срд 27 Ноя 2013 18:23:01  #445 №338082 

>>337971
Ничего не делать, очевидно же. Вдруг ты действительно не пригоден?

Аноним Срд 27 Ноя 2013 18:49:07  #446 №338091 

>>338074
Диплом нужен для выполнения госзаказов. Отчётность.

>попытаюсь устроиться во все конторы своего города
Это не все конторы, а те, куда никто не хочет идти. А так как сами они прекрасно об этом знают, то и фраза:

>а вдруг я никому нахуй не буду нужен
Окажется верна! Гораздо страшнее, если ты им будешь нужен, тогда мы больше о тебе (и от тебя) ничего не услышим.

Т.е. искать надо долго и тщательно, и диплом тут поможет мало, а наличие его отсутствия - так и вовсе ни при чём.

Аноним Срд 27 Ноя 2013 19:54:17  #447 №338096 

>>338091
>попытаюсь устроиться во все конторы своего города
Это не все конторы, а те, куда никто не хочет идти. А так как сами они прекрасно об этом знают, то и фраза:
>а вдруг я никому нахуй не буду нужен
Окажется верна! Гораздо страшнее, если ты им будешь нужен, тогда мы больше о тебе (и от тебя) ничего не услышим.
Нихуя не понял джпег.

Аноним Срд 27 Ноя 2013 19:59:47  #448 №338097 

recursive-descent калькулятор на питоняше http://ideone.com/YzGnNP

Аноним Срд 27 Ноя 2013 20:42:17  #449 №338107 

>>338097
>scip

Аноним Срд 27 Ноя 2013 20:57:03  #450 №338109 

>>338107
Давно пора было влючить спеллчек в виме, спасибо.

!xnn2uE3AU. Срд 27 Ноя 2013 23:24:51  #451 №338131 

>>338097

Выражение вроде - - - - 2 не поддерживается? А так, да, работает, да еще и на всяких генераторах с итераторами.

Аноним Срд 27 Ноя 2013 23:32:29  #452 №338132 

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

!xnn2uE3AU. Срд 27 Ноя 2013 23:45:54  #453 №338138 

>>338132

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

Часть информации я собираю в пасты (несколько есть в разделе «Ооп и пасты» на сайте).

Аноним Чтв 28 Ноя 2013 00:21:20  #454 №338144 

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

!xnn2uE3AU. Чтв 28 Ноя 2013 00:38:57  #455 №338146 

>>338144

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

> Вроде ж пхп умеет, при таком раскладе, передавать идентификатор сессии через URL.
Он умеет при выводе страницы подставлять идентификатор в ссылки. Но во-первых, это кривой ненадежный костыль, во-вторых, это небезопасно так как при переходе на другой сайт, или загрузке любой внешней картинки URL (с идентификатором сессии) передается в реферере. Ни в коем случае не включай эту настройку. А, и еще при таком способе можно сделать атаку фиксации сессии: http://www.securityscripts.ru/articles/PHP/session-fixation.html

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

Аноним Чтв 28 Ноя 2013 11:19:24  #456 №338211 


Сап, програмач.
Разъясни по хардкору.
Битый час пытаюсь вникнуть в суть, курю холивары. до сути не дошел.
Собствено сабж - чем плох GOTO? DВ чем блять?
Все холивары сводятся к ко-ко-ко нечитаемость кода.
Ко-ко-ко не нужен, можно без него.
А нахуя без него, лепить лишние овер9000 конструкций, когда въебал один goto и отправился нахуйк нужному участку кода?
Вот и в PHP 5.3 ввели goto.
Короче. Гуру, разъясните же, в чем дзен?

!xnn2uE3AU. Чтв 28 Ноя 2013 11:58:08  #457 №338223 

>>338211

Разъясняю. goto обычно используют люди, которые не умеют разбивать код на функции, не умеют правильно использовать циклы, а лепят код одной длинной портянкой. В таком коде, естественно, без goto вообще ничего работать не будет. Видимо, для них его и добавили. В PHP много странных вещей.

Потому ичпользовать goto = поощрять быдлокодинг. Правильнее научиться писать аккуратный структурированный код.

!xnn2uE3AU. Чтв 28 Ноя 2013 11:59:26  #458 №338224 

>>338211

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

Аноним Чтв 28 Ноя 2013 12:10:54  #459 №338226 

>>338224
http://blog.gamedeff.com/?p=161

Аноним Чтв 28 Ноя 2013 12:17:07  #460 №338227 

>>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 может быть недостаточно и он может делать код запутанным.

!xnn2uE3AU. Чтв 28 Ноя 2013 12:45:35  #461 №338231 

>>338227

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

Аноним Чтв 28 Ноя 2013 12:57:14  #462 №338232 

>>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 имеет исторический контекст. Она была призвана перетащить прикладных программистов того времени на струтурное программирование. Я выше писал, что код должен быть в основном структурным, но мне не нравится такое религиозное отношение к вещам, осмысленное применение которых очень зависимо от контекста.

!xnn2uE3AU. Чтв 28 Ноя 2013 12:57:25  #463 №338233 

>>338227
>>338226

1) это не PHP
2) разработчики ядра линукс своеобразные люди. Они и на ООП переходить не желают.
3) разработчики Windows тем более своеобразные

Аноним Чтв 28 Ноя 2013 13:08:03  #464 №338236 

>>338233
>> 1) это не PHP

Твое первоначальное заявление было о ненужности goto, а не о goto в PHP.

>> 2) разработчики ядра линукс своеобразные люди. Они и на ООП переходить не желают.

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

Аноним Чтв 28 Ноя 2013 13:11:53  #465 №338237 

>>338224
Без goto всегда можно обойтись. Это не аргумент против него, потому что обойтись можно без всех высокоуровневых языков например.

!xnn2uE3AU. Чтв 28 Ноя 2013 13:12:53  #466 №338238 

>>338232

Я ни раз в PHP не встречал необходимости в goto.

> Конечный автомат безусловно можно писать руками и, как ни странно, семантика goto эквивалентна семантике state transition. Никакой лапши, никакого "плохого дизайна".
Сомневаюсь. Если ты пишешь огромную функцию на 2000 строк, это нечитаемая лапша с высокой вероятностью ошибок например из-за повторного использования переменных.

> О пользе goto на низком уровне
Как может быть «низкий уровень» на PHP? Байткод руками писать что ли? Пиши на Си лучше.

> То, что что-то "генерируется" вообще иррелевантно.
Что за бред. Сгенерированный код никто не будет читать и править, потому в нем можно писать что угодно. А в обычном — нет.

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

Аноним Чтв 28 Ноя 2013 13:18:32  #467 №338239 

>>338238
>> Я ни раз в PHP не встречал необходимости в goto.

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

>> Что за бред.

Ты не понял, читай ниже.

>> Да ну, сомневаюсь.

А вообще-то не спорю с тобой, а говорю, что это так. Как пример - любой компилятор C++. Это просто пример того, что иногда генерация чего-то может не подойти. В частности из за производительности результирующего кода.

Аноним Чтв 28 Ноя 2013 13:19:32  #468 №338240 

Кстати механизм классов часом не на goto основан?

Аноним Чтв 28 Ноя 2013 13:36:35  #469 №338242 

>>338238
>Я ни раз в PHP не встречал необходимости в goto.
Мало программистов вообще встречают такую необходимость. 90% занимаются написанием примитивного говна вроде веб-сайтов.

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

!xnn2uE3AU. Чтв 28 Ноя 2013 13:49:19  #470 №338244 

>>338242

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

Ты ведь не думаешь, что программы тормозят из-за вызовов функций и оптимизируются объединением кода в один большой кусок кода с goto?

Аноним Чтв 28 Ноя 2013 14:03:18  #471 №338248 

>>338244
>Расскажи нам пример такой задачи.
Тестер стратегий например.

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

>Ты ведь не думаешь, что программы тормозят из-за вызовов функций и оптимизируются объединением кода в один большой кусок кода с goto?
Думаю. Объединение (или разбиение) функций и использование гото давало где-то процентов 5-15% к скорости, плохо помню уже. инбифо: не надо мне рассказывать какие есть еще другие более эффективные способы оптимизации, я их получше тебя знаю

!xnn2uE3AU. Чтв 28 Ноя 2013 14:06:28  #472 №338249 

>>338248

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

Аноним Чтв 28 Ноя 2013 14:12:42  #473 №338253 

>>338249
Я и не пишу на PHP и вообще его не знаю, мимокрокодил, заглянул в вашу веб-парашу. Кстати, вам же тоже сделали гото в пхп. По-началу его не было, видимо создатель повелся на стадный инстинкт ненависти к гото, а потом, после многих лет и практики поняли что гото нужен, а дейкстра просто был в истерике, а программисты, пошедшие за ним - просто тупое стадо. Вам и ООП завезли недавно. Еще бы статическую типизацию и язык станет годен для разработки больших проектов.

!xnn2uE3AU. Чтв 28 Ноя 2013 14:30:54  #474 №338254 

>>338253

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

Аноним Чтв 28 Ноя 2013 14:36:52  #475 №338256 

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

Аноним Чтв 28 Ноя 2013 14:41:29  #476 №338257 

ОП, можешь объяснить в чем суть?

http://viper-7.com/YXiphB
http://viper-7.com/DyQ4LU

Прежде всего непонятно, почему перезаписанный private метод в первой пасте вызывается из родителя, но перезаписанный protected метод - из потомка.

Могу предположить, что учитывая то, что test() вызван в контексте родителя, а private методы в отличие от protected видны только в контексте класса, где они определены, он не может "подтянуть" его в область видимости из потомка, но всё равно какая-то путаница в голове.

!xnn2uE3AU. Чтв 28 Ноя 2013 14:58:58  #477 №338260 

>>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 это разные, не связанные друг с другом методы.

Аноним Чтв 28 Ноя 2013 20:49:20  #478 №338320 

Задачка про считалку.

http://ideone.com/5c0HD6

Опчик, так правильно?

!xnn2uE3AU. Чтв 28 Ноя 2013 22:23:44  #479 №338329 

>>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, неужели она это может?

Аноним Птн 29 Ноя 2013 04:50:59  #480 №338440 

ОП, посмотри сюда, пожалуйста.

Есть чужой хостинг. На нем:
мускуль на апаче, схема и таблицы в UTF-8;
там же пхп5.3 с mb_internal_encoding() тоже UTF-8;

Читаем через PDO кирилицу, она приходит в аскии. И, соответственно, ее strlen() равен количеству символов, а не ожидаемому кол-ву байт. Хоть срись.

На локальном хостинге все нормально, но он умер. Где еще искать, кроме как не в кодпейджах мускула и пхп? Отдельной настройки для ПДО не знаю, хотя подозреваю именно его.

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

Аноним Птн 29 Ноя 2013 05:03:46  #481 №338441 

>>338440
Ипать колотить, я лох. Пол-ночи возился, сдался, задал вопрос и тут же нашел как надо:

В аргумент конструктору ПДО надо добавить ';charset=UTF8'

Аноним Птн 29 Ноя 2013 11:51:40  #482 №338470 

>>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.

Аноним Птн 29 Ноя 2013 12:39:23  #483 №338477 

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

Аноним Птн 29 Ноя 2013 12:44:57  #484 №338478 

>>338470

>empty($a) and $a = 'vocaroo';
Плохой код, лучше писать более очевидно:

$a = empty($a) ? 'vocaroo' : $a;

Тут сразу по началу строчки видно что мы что-то присваиваем в $a.

> empty() приводит к булеву значению, т.е. 0 тоже будет считаться пустой переменной.
Обычно так и требуется.

> Если же использовать isset(), то пустая строка вернет true.
Лучше использовать явную проверку на null: $a === null

Аноним Птн 29 Ноя 2013 12:52:31  #485 №338482 

>>338470

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

Также, у нас есть задачка на фреймворки - сделать свой аналог rghost на микрофреймворке.

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

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

Аноним Птн 29 Ноя 2013 14:39:51  #486 №338498 

>>338482
У меня как раз список задач на данный момент: мышки, рест-сервис, рг-хост.

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

>Плохой код, лучше писать более очевидно: $a = empty($a) ? 'vocaroo' : $a;
Дак да, но тот анон явно сказал, что хочет без тернарника. Собственно поэтому и написал сразу "изъебнуться". Не как полезный пример, а как пример того, что в пыхе таки это возможно.

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

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

Аноним Суб 30 Ноя 2013 10:33:44  #487 №338655 

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

http://ideone.com/2Gp5Vt

Аноним Суб 30 Ноя 2013 10:39:05  #488 №338656 

>>338482
>MVC

Что такое MVC? Вики говорит Model-View-Controller
Но там как-то сложно всё. Можете в двух словах объяснить о чем конкретно речь идёт здесь? Что такое архитектура MVC?

Аноним Суб 30 Ноя 2013 14:32:05  #489 №338706 

Про круг:
http://ideone.com/gRFXaX

Аноним Суб 30 Ноя 2013 16:01:45  #490 №338728 

>>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-приложение, например борду.

Аноним Суб 30 Ноя 2013 16:04:21  #491 №338729 

>>338656

Алсо, в статье http://ru.wikipedia.org/wiki/Model-View-Controller есть пример кода на PHP5. Учтите, он довольно-таки отстойный, не стоит с него брать пример.

Аноним Суб 30 Ноя 2013 16:17:54  #492 №338735 

>>338655

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

Например, я не помню, если мы удаляем текущий элемент через unset($positions[$cur]); — куда смещается указатель? На предыдущий или на следующий элемент или это поведение не определено? Эти манипуляции с указателем — очень неочевидная вещь, и я бы советовал тебе вообще избегать использование next/current/prev и подобных функций.

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

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

Потому в дальнейшем старайся все-таки писать попроще.

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

Аноним Суб 30 Ноя 2013 16:24:09  #493 №338738 

>>338706

Что-то у тебя круг не круглый. Видимо там шрифт очень узкий и высокий и надо подобрать другой коэффициент (не 1.7 а больше).

> $x = round(($centerX + $hor) * 1.7);
Я думаю, надо умножать только $hor а не всю сумму.

> foreach ($screen as $value) {
> foreach ($value as $char) {
давай-ка ради улучшения кода попробуем обойтись без foreach, например с помощью implode?

Аноним Суб 30 Ноя 2013 17:06:51  #494 №338755 

>>338735
>Например, я не помню, если мы удаляем текущий элемент через unset($positions[$cur]); — куда смещается указатель? На предыдущий или на следующий элемент или это поведение не определено?

Я опытным путём установил, что смещается на следующий. Да я согласен, что код говно.

>>338728
Правильно ли я понял что так называемая концепция "ненавязчивого javaScript" отделения js кода от структуры документа - разметки html, а также отделение представления от структуры (css, когда таблицы стилей выносятся в отдеьные файлы) и php не в перемешку с html а тоже структурировано и в отдельных файликах это и есть MVC. То есть если я так делаю при разработке той же борды, то я использую эту модель?

Аноним Суб 30 Ноя 2013 17:27:17  #495 №338769 

>>338755

> Я опытным путём установил, что смещается на следующий.
Хорошо, если это описано в мануале и гарантируется. А что если это недокументированная особенность, и в следующей версии PHP, например, перепишут код работы с массивом и он начнет смещаться по другому принципу? Или он начнет смещаться в зависимости от 32- или 64-битной версии? Вот будет весело, искать причину почему на одном сервере код работает правильно, а на другом нет.

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

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

Аноним Суб 30 Ноя 2013 17:40:54  #496 №338773 

>>338755

> Правильно ли я понял что так называемая концепция "ненавязчивого javaScript" ... и php не в перемешку с html а тоже структурировано и в отдельных файликах это и есть MVC
Нет. MVC — это когда есть модели, вьюшки и контроллеры. А разделение страницы на разметку (HTML), оформление (CSS) и поведение (JS) — это другое. Ненавязчивый яваскрипт — вообще третье.

Идея с unobtrusive javascript была такая:

- пишем HTML/CSS страницы так, чтобы она работала без яваскрипта. Например, формы отправляются стандартным способом, ссылки работают как ссылки.
- затем, подключаем к ней внешний JS-файл. Если браузер поддерживает яваскрипт, и файл загрузился без ошибок, то этот код ставит свои обработчики на страницу, постепенно улучшая ее (progressive enhancement) и например, при вводе значений в поля формы они автоматически валидируются, отправка формы делается без перезагрузки аяксом, и так далее.

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

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

Аноним Суб 30 Ноя 2013 20:45:57  #497 №338824 

Помогите ньюфагу. Установил 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, но легче от этого не стало.

sageАноним Суб 30 Ноя 2013 21:08:09  #498 №338830 

>>338824
Апач перезапускал, mbstring в phpinfo() видно? Не тот php.ini правил?

Аноним Суб 30 Ноя 2013 21:35:05  #499 №338839 

>>338830
Перезапускал, в phpinfo() его нет. php -m выдает http://pastebin.com/qNEeuJzQ.
php.ini тот который php.ini-production. В не же правил строку extension_dir.

Аноним Суб 30 Ноя 2013 22:00:59  #500 №338853 

>>338830
Все, разобрался, таки php.ini не тот был. Спасибо за помощь.

Аноним Суб 30 Ноя 2013 22:20:43  #501 №338861 

>>338853

В следующий раз смотри phpinfo() — там выводится путь к использованному файлу с конфигом. В командной строке можно набрать php --ini .

Аноним Суб 30 Ноя 2013 22:41:18  #502 №338864 

Пхп-сенсеи, дайте ссылок на сырки имиджборд на чистых PHP + JS.

Аноним Пнд 02 Дек 2013 12:19:40  #503 №339198 

Семпай, помоги разобраться.
Читаю исходники Slim, никак не могу сообразить в методе singleton() класса Slim\Helper\Set.

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

Код метода:
http://pastebin.com/0XqbN6Ps
Код класса:
http://pastebin.com/BK2JGnc3

Аноним Пнд 02 Дек 2013 12:31:07  #504 №339199 

А вот пример использования.
http://pastebin.com/NZ0mA9A7

Что-то я совсем в этих замыканиях заблудился.

Аноним Пнд 02 Дек 2013 12:31:55  #505 №339200 

>>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 ).

--

Алсо, скоро перкатимся в новый тред.

Аноним Пнд 02 Дек 2013 12:44:35  #506 №339202 

>>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);

Аноним Пнд 02 Дек 2013 12:56:18  #507 №339204 

>>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')

Если тебе потом захочется более глубоко изучитьт ФП, почитай про Хаскелл.

Аноним Пнд 02 Дек 2013 13:53:51  #508 №339214 

>>339200
От жеж, код метода get() тоже просматривал, а на передачу аргумента в конце $this->data[$this->normalizeKey($key)]($this) не обратил внимание. Спасибо, теперь понял.

Нет бы этот $c назвать $that или еще как-нибудь попонятней.

Алсоу, вроде как функции принимающие и передающие (и создающиеся в рантайме) это просто ф-ции первого класса, а ФП - это уже пучина отсутствия стейта и императивных команд и прочих извращений, не? Или как раз ф-ции как объекты первого класса - отличительная черта ФП?

Задачки попозже попробую решить. Хаскель как-то не прельщает, но элементы ФП интересны, скорее не для PHP даже, а в контексте JS. Backbone.js, Underscore.js, вот это вот всё.

Кстати, раз уж за ФП разговор прошел. Ты SICP случаем не читал? Как считаешь, стоит оно того? Сам знаешь, какая у этой книги слава, мол, дарует интеллектуальное просветление, жизнь никогда не будет прежней, etc.

Алсоу_2, а чего ты от трипкода избавился?

!xnn2uE3AU. Пнд 02 Дек 2013 14:20:34  #509 №339219 

>>339214

> Нет бы этот $c назвать $that или еще как-нибудь попонятней.
Передается вроде бы туда $slim->container, логично его назвать $container, а $c — это сокращение от него.

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

> Алсоу, вроде как функции принимающие и передающие (и создающиеся в рантайме) это просто ф-ции первого класса, а ФП - это уже пучина отсутствия стейта и императивных команд и прочих извращений, не? Или как раз ф-ции как объекты первого класса - отличительная черта ФП?
Упс, тут я понял, что сам не особо разбираюсь в функциональщине. Но в примерах кода в задании — переменных и императивных команд вроде и нету, только функции (ок, мы храним их в переменных но только потому, что без них будет нечитабельно).

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

Аноним Пнд 02 Дек 2013 16:35:40  #510 №339286 

http://ideone.com/4DKBhk

БЛДЖАД, ДА ЧТО НЕ ТАК С ЭТОЙ СТРОКОЙ?! Опчик, выручай.

Аноним Пнд 02 Дек 2013 16:38:51  #511 №339289 

>>339286
Поясню, выдаёт синтаксическую ошибку на 177 строке.

!xnn2uE3AU. Пнд 02 Дек 2013 17:03:44  #512 №339300 

>>339289

Упс, похоже ты уже все исправил. Ну молодец.

Аноним Пнд 02 Дек 2013 18:24:44  #513 №339319 

Ничего я не исправил, по-прежнему не работает же.

!xnn2uE3AU. Пнд 02 Дек 2013 18:31:32  #514 №339321 

>>339319

Тогда ссылку покажи. По ссылке http://ideone.com/4DKBhk я не вижу синтаксических ошибок. Там есть только

PHP Notice: Undefined index: nov in /home/schbsP/prog.php on line 184

А это просто ошибка что в массиве в строке 184 нет нужного ключа, а ты пытаешьс его прочесть. Натыкай var_dump() и посмотри что в переменных.

Аноним Пнд 02 Дек 2013 19:39:09  #515 №339343 

>>339321
Фух, разобрался!

http://ideone.com/I4njoh

!xnn2uE3AU. Пнд 02 Дек 2013 19:54:48  #516 №339348 

>>339343

По алгоритмам советую начать с Википедии. Там есть список алогоритмов.: http://ru.wikipedia.org/wiki/Поиск_пути Один анон например Дийкстрой делал.

!xnn2uE3AU. Пнд 02 Дек 2013 20:15:27  #517 №339354 

Хочу возмутиться. MySQL, как известно, позволяет указать при создании таблицы ограничение для колонки (CHECK(....)) но оно в лучших традициях MySQL не работает: http://stackoverflow.com/a/14247690

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

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

Алсо, скоро перекат.

Аноним Пнд 02 Дек 2013 21:13:19  #518 №339368 

>>339348
Опять поторопился, половина маршрутов не работала. Ну теперь-то точно всё. Так я тоже по алгоритму Дейкстры делал.
Там такая-статья про него хорошая и понятная на Википедии.

http://ideone.com/PfQWQA - теперь, по-моему, всё работает.

Оп, а есть задачки с MySQL поучиться работать чтобы?

!xnn2uE3AU. Пнд 02 Дек 2013 21:38:54  #519 №339374 

>>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 самых популярных пользователей.

!xnn2uE3AU. Пнд 02 Дек 2013 21:40:51  #520 №339375 

>>339374

В качестве решения надо: дать SQL-запросы, который создают таблицы и набивают их данными и SQL-запрос который эти данные выбирает в нужном виде. Ну или просто дать ссылку на sqlfiddle с решением.

!xnn2uE3AU. Пнд 02 Дек 2013 22:13:10  #521 №339384 

>>339374

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

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

!xnn2uE3AU. Пнд 02 Дек 2013 23:39:45  #522 №339425 

продолжаем изучать PHP в новом треде: >>339400

Аноним Пнд 09 Дек 2013 23:28:05  #523 №341502 

>>333488
Ты в Notepad'е код пишешь?

comments powered by Disqus

Отзывы и предложения