Этого треда уже нет.
Это копия, сохраненная 4 марта 2015 года.

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

Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
33 Кб, 500x500
34 Кб, 650x384
157 Кб, 1024x683
435 Кб, 600x900
Клуб изучающих PHP 43 #431924 В конец треда | Веб
Добро пожаловать. В этом треде мы изучаем язык PHP (а также JS/CSS/HTML/SQL), решаем задачки и даже делаем простые сайты! Зачем? Кто-то хочет научиться программировать, кто-то - делать сайты, кто-то - просто размять мозги и заняться чем-то полезным.

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

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

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

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

У нас есть уроки по основам PHP, они собраны и выложены по адресу http://archive-ipq-co.narod.ru/ Это учебник для изучающих с нуля, то есть если ты вообще ничего не знаешь, то надо начать с него. Он простой и понятный (по крайней мере в начале). Там есть задачи, их надо решать обязательно (чтобы стать программистом, надо писать код — иначе никак). Пости ссылки на решения в тред, мы их проверим, напишем замечания и дадим советы по улучшению.

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

Учебник дает основы языка PHP, но чтобы делать сайты, этого недостаточно. Если ты его прошел, то надо переходить в более серьезным задачкам, которые научат тебя как выдавать страницы в браузер, работе с таблицами в БД, работе с формами, MVC.

- Простая, но полезная задача сделать список студентов: https://gist.github.com/codedokode/d7e7f11449fc3bcb24b4
- Более сложная задача сделать файлообменник на микрофреймворке Slim: https://gist.github.com/codedokode/9424217
- Еще более сложная и долгая задача на Yii/Yii2: https://gist.github.com/codedokode/8733007
- Если ты все их решил, переходи к Symfony 2/Doctrine 2

Чтобы делать эти задания, тебе надо установить Апач + PHP (можно заодно сразу и MySQL) на компьютер. Вот полезные инструкции:

https://gist.github.com/codedokode/10774100
https://gist.github.com/codedokode/7054af4a03865c4cc863

Может тебе понадобится пользоваться командной строкой, вот гайд https://gist.github.com/codedokode/10539568

Вот небольшой туториал по тому как начать использовать PHP на сервере для отдачи странички в браузер: https://php.net/manual/ru/tutorial.php Увы, уроков плавно подводящих к тому, как сделать задачи выше, пока нет, так что если что, задавай вопросы.

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

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

- HTML/CSS: https://gist.github.com/codedokode/58ebc90bd006baf4b35c
- JS: https://gist.github.com/codedokode/ce30e7a036f18f416ae0
- Проверялка решений на JS: http://dkab.github.io/jasmine-tests/
- MySQL: https://gist.github.com/codedokode/10539213

Что почитать

- Мануал по PHP — http://www.php.net/manual/ru/langref.php
- Сайт phptherightway (перевод на русский: http://getjump.github.io/ru-php-the-right-way/ )
- По PHP: Профессиональное программирование на PHP Джордж Шлосснейгл
- По PHP: Мэтт Зандстра — PHP: Объекты, шаблоны, методики программирования
- JS: learn.javascript.ru
- Про Git:

Нужен ли ООП, фреймворки, MVC? — Да, однозначно. Посмотри любую вакансию.
Сайт опять упал!!!!! — Не паникуй, а открой http://rghost.net/45000175
Оформляй код аккуратно!!! — например пропусти через phpformatter.com . Также, если ты пользуешься IDE вроде PhpStorm, Netbeans, Eclipse, то в них эта опция встроена, подробнее: https://gist.github.com/codedokode/8759492
ОП, сделай за меня мою работу или домашнее задание? — Это конечно, хорошая идея, но нет.
Где искать работу и заказы — hh.ru, geekjob.ru, brainstorage.me, fl.ru, odesk.com. Имей в виду, что кроме фриланса есть еще постоянная удаленная работа (remote job) когда тебе не надо тратить время на поиск заказов и переговоры с неадекватными заказчиками.
56 Кб, 500x644
Пиши верно #2 #431927
Код надо писать не как попало, а аккуратно и по правилам. Почему? Потому, что на неакуратно написанный код не хочется даже смотреть.

Если тебе лень выравнивать код руками, закачай его на http://beta.phpformatter.com/ и нажми «format». Робот исправит выравнивание и отступы в мгновение ока (да, прогресс не стоит на месте). Если ты используешь мощную IDE вроде PhpStorm, там тоже есть функция форматирования кода.

Горячие клавиши для форматирования кода в разных IDE: https://gist.github.com/codedokode/8759492

Вообще, в PHP долгое время не было единого стандарта оформления кода, все писали как попало и было много бардака, но сейчас дело лучше — есть стандарты PSR-1 и 2. Вот как надо оформлять код:

- переменные и функции пишутся с маленькой буквы, подчеркивание не используется, используется camelCase, пример: $x, $numberOfPeople, printResults()
- Название функции начинается с глагола, в стиле «сделайЧтоТо»
- не знаешь английский? Не беда, в 21 веке есть решение этой проблемы. Не пиши транслитом, открой лучше Гугл Транслейт или slovari.yandex.ru и найди название для переменной там
- в именах классов используется CamelCase, первая буква большая, «_» может использоваться
- мы предпочитаем подстановку переменных вместо конкатенации строк: "I am $age years old" — хорошо, 'I am ' . $age . ' years old' — плохо из-за обилия точек и кавычек
- мы используем для отступов 4 пробела (можно настроить редактор, чтобы при нажатии Tab он вставлял 4 пробела)

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

PSR-1: https://github.com/php-fig/fig-standards/blob/master/accepted/ru/PSR-1-basic-coding-standard.md
PSR-2: https://github.com/php-fig/fig-standards/blob/master/accepted/ru/PSR-2-coding-style-guide.md
#3 #431930
Чтобы не забыть проверить:

> https://github.com/MindiMakridi/Students Исправил вроде, кроме переменных.

sage #4 #432023
>>431162
https://github.com/tokotun/matriculant

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

Завтра буду делать доступ к полям класса private/protected. И прописывать к ним методы.
#5 #432059
Есть у меня один проект, бекенд полностью на пхп, передает данные в виде json. Так вот у меня возникла ситуация, что доступ к бд пропал, а наполнить какими-нибудь тестовыми данными приложение нужно. Как бы мне это максимально быстро и просто сделать? Закоментил весь код, связанный с получением данных из бд, а что дальше делать не знаю. Не хардкодить же прям в этих пхп файлах данные.
#6 #432063
>>432059
Так тебе бекенд надо наполнить или фронт?
#7 #432065
>>432063
Наполнить надо фронтенд, но все данные приходили через ajax. В пхп у меня собственно и были все обращения к базе и получение всей нужной информации, после чего передавал json на фронт.
#8 #432070
>>432065
Ну и почему бы не захардкодить? Сделай скрипт заглушку один раз для таких случаев. Ну или посмотри в сторону firebase
#9 #432072
>>432070

Зачем смотреть в строну firebase если можно использовать ту же БД что использовалась ранее и залить в нее небольшой тестовый дамп.
someApprentice #10 #432118
>>431172

>5 значений ширины у одной картинки? и все публичные? Я не понимаю, что это вообще значит.



$width - исходная ширина
$maxWidth - максимальная ширина, заданная пользователем
$newWidth - Новая ширина, вычисляемая для "вырезания" изображения из оригинала и вставки его в новое изображение
$cropX - Количество пикселей которые надо обрезать
$newWidth_p - Новая ширина, для нового изображения, в которое будет вставлен обрезанный оригинал.

>Метод createThumbnailеще хуже. Чтобы он работал корректно, надо сначала задать значения полей $this->newWidth_p, $this->newHeight_p, $this->x, $this->y, $this->cropX, $this->cropY, $this->newWidth, $this->newHeight но как программист об этом догадается? Это не метод, а мина замедленного действия которая рано или поздно сломает код.


>Надо сначала задать значения полей


Они задаются сначала, функцией calculateImage.

>но как программист об этом догадается?


А как я догадаюсь, о чем догадается программист?

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


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

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

>Это не метод, а мина замедленного действия которая рано или поздно сломает код.


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

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

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

Как в общем узнать к чему стремиться?
someApprentice #10 #432118
>>431172

>5 значений ширины у одной картинки? и все публичные? Я не понимаю, что это вообще значит.



$width - исходная ширина
$maxWidth - максимальная ширина, заданная пользователем
$newWidth - Новая ширина, вычисляемая для "вырезания" изображения из оригинала и вставки его в новое изображение
$cropX - Количество пикселей которые надо обрезать
$newWidth_p - Новая ширина, для нового изображения, в которое будет вставлен обрезанный оригинал.

>Метод createThumbnailеще хуже. Чтобы он работал корректно, надо сначала задать значения полей $this->newWidth_p, $this->newHeight_p, $this->x, $this->y, $this->cropX, $this->cropY, $this->newWidth, $this->newHeight но как программист об этом догадается? Это не метод, а мина замедленного действия которая рано или поздно сломает код.


>Надо сначала задать значения полей


Они задаются сначала, функцией calculateImage.

>но как программист об этом догадается?


А как я догадаюсь, о чем догадается программист?

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


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

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

>Это не метод, а мина замедленного действия которая рано или поздно сломает код.


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

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

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

Как в общем узнать к чему стремиться?
#11 #432238
>>431924
Оп подскажет как лучше подключать скрипты?
как быстрее?
так: <script src="http://code.jquery.com/jquery-1.9.0.js"></script>
или так: <script type="text/javascript" src="js/jquery.simplemodal.js"></script>
#12 #432273
Посоветуете чего бы не сильно сложного сделать на yii, а то читаю мануал, а без практики уныло совсем. Задачу с тестами пока не решаюсь начинать, ибо не вкурил еще во фреймворк.
#13 #432293
>>432238
Я не оп, конечно, но первый вариант может подвести тебя. Был недавно случай, я на хабре видел, как кто-то хакнул этот самый jquery cdn и что-то подсовывал вместо кошерного jquery (или просто что-то дописал в код библиотеки, типа тут был васян). Иногда эти сервера просто недоступны (хотя может это просто слухи). Один фиг, я считаю лучше сжать, прогнать через минифаер и сервить самому. Инетерсно послушать другие мнения.
#14 #432304
>>432072
Ну тестовый дамп наверно не подойдет, т.к название полей, таблиц и т.д нельзя показывать. Нужно что-нибудь типа локальных файлов с данными.
#15 #432309
>>432238
Лучше это относительное понятие. Если ты делаешь коммерческий продукт и твой хостинг-провайдер может обеспечить аптайм больше/выше чем CDN, грузи к нему. Если нет, используй CDN. Что касается скорости, могу предположить что это вопрос географического расположения серверов и настроек сети. Но с трудом могу представить при каких нагрузках это может оказать заметное влияние. В целом я бы рекомендовал грузить все себе, просто потому что например можно по ходу дела ознакомится с бовером ну и даже поглядеть исходники тех бибилиотек что используешь, это всегда полезно.
#16 #432310
>>432309
Забыл подписаться, не ОП
sage #17 #432316
>>432118
Стремись к этому. http://learn.javascript.ru/write-unmain-code

Неплохая статья даёт общее понимание о том как писать код.
#18 #432319
>>432238

Со своего сервера. Удаленный сервер может:

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

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

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

Если кратко: подключать скрипты с чужих CDN профита нет, риски даунтайма есть.

Более того, обычно современный сайт весит полмегабайта-мегабайт и я не вижу вообще выгоды от переноса одного 30-килобайтового скрипта на CDN. А зачем тогда в твиттере и западных блогах и учебниках пиарят такой способ? Не знаю, может компании-владельцы CDN хотят собирать статистику кто на какие сайты заходит?
#19 #432323
>>432309

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


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

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

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

А выносить один-единственный скрипт вообще смысла никакого нет.
#20 #432324
>>432304

Сделай JSON файлы и отдавай их. Алсо, если есть описание АПИ и возвращаемых результатов в машинночитаемом виде, данные можно генерировать программно.

Но вообще задача надуманная. быстрее и проще дать тестовый дамп, а все что ты написал только замедляет разработку. Я надеюсь, всю эту возню хотя бы оплачивают.
#21 #432327
>>432273

Сделай задачу про регистрацию абитуриентов тогда на Юи. Без генераторов, пиши руками. Также, по максимуму используй стандартные компоненты Юи и по минимумму пиши свой код.
#22 #432329
>>432327

Например, для отображения таблиц с сортировкой в Юи есть готовый компонент — грид. Надо использовать именно его, а не писать свой велосипед. Аналогично, там есть средства для вывода и обработки форм.
#23 #432333
Аноны, тут может кто-то работает фрилансером, может у кого сейчас много заказов и есть несложная работа по ПХП, можете дать своё задание? Хочу попробовать свои силы в этом.
#24 #432346
>>432118

>> но как программист об этом догадается?


> А как я догадаюсь, о чем догадается программист?


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

Хорошая функция получает аргументы, что-то с ними делает и возвращает результат. Ее название понятно и объясняет что она делает:

$result = goodFunction($a, $b, $c);
$rubles = convertDollarsToRoubles($dollars, $rate);

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

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

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

// сначала мы должны вызвать prepare и установить курс иначе функция ниже не заработает:
prepareConverting($rate);

// Также мы должны выставить глобальные переменные, которые задают валюту перевода
$convertFrom = 'USD';
$convertTo = 'RUR';

// Сумма в долларах должна быть помещена в POST:
$_POST['sum']['dollars'] = 100500;

// Функция выведет результат на экран, а не вернет в переменную потому сделать мы с ним ничего не можем
convertToRubles( );

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

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

Хороший ООП код предпочитает ислоьзовать объекты вместо сложных массивов.

Вот пример хорошего объекта, который позволяет сохранять посты в блоге в базе данных:

class PostMapper {
public function __construct(PDO $pdo) { ... }
public function save(Post $post) { .... }
public function validate(Post $post) { ... }
.... непубличные методы не показаны ...
}

// Так как для работы объекта нужен PDO, то мы передаем его при создании
$postMapper= new PostMapper($pdo);

// Создаем объект-пост
$post = new Post( );
$post->setTitle('Один день Ивана Ивановича');
$post->setText(...);

// сохраняем в базу
$postMapper->save($post);

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

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

Вот пример плохого класса:

// Сначала надо вызвать Connect иначе он не сможет соединиться с БД
PostMapper::$pdo = $pdo;
PostMapper::connect( );

// Затем надо создать массив с информацией о посте
$postArray = array(
'title' => 'Один день Ивана Ивановича',
'text' => '....',
'author' => 'Anonymous'
);

// Массив надо обработать иначе пост вставится, но без текста
DataProcessor::processDataArray($postArray);

// Дата добавления передается в MySQL-формате
$_POST['added'] = '2015-01-01 12:00:00';

// Не забыть выставить имя таблицы, а то вставится комментарий вместо поста!
PostMapper::$tableName = 'posts_table';

// Подготавливаем SQL-запрос - не забыть что тут нестатический метод
$postMapper= new PostMapper( );
$postMapper->prepareQuery( );

// делаем вставку в базу данных c помощью отдельного класса (каждый должен заниматься своим делом!)
SomeOtherClass::insertIntoDatabase( );

Вот как-то так. Надеюсь, что примеры дадут хотя бы немного понимания, как надо и как не надо писать. Если что-то тут непонятно или кажется неправильным, так и пиши.
#24 #432346
>>432118

>> но как программист об этом догадается?


> А как я догадаюсь, о чем догадается программист?


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

Хорошая функция получает аргументы, что-то с ними делает и возвращает результат. Ее название понятно и объясняет что она делает:

$result = goodFunction($a, $b, $c);
$rubles = convertDollarsToRoubles($dollars, $rate);

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

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

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

// сначала мы должны вызвать prepare и установить курс иначе функция ниже не заработает:
prepareConverting($rate);

// Также мы должны выставить глобальные переменные, которые задают валюту перевода
$convertFrom = 'USD';
$convertTo = 'RUR';

// Сумма в долларах должна быть помещена в POST:
$_POST['sum']['dollars'] = 100500;

// Функция выведет результат на экран, а не вернет в переменную потому сделать мы с ним ничего не можем
convertToRubles( );

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

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

Хороший ООП код предпочитает ислоьзовать объекты вместо сложных массивов.

Вот пример хорошего объекта, который позволяет сохранять посты в блоге в базе данных:

class PostMapper {
public function __construct(PDO $pdo) { ... }
public function save(Post $post) { .... }
public function validate(Post $post) { ... }
.... непубличные методы не показаны ...
}

// Так как для работы объекта нужен PDO, то мы передаем его при создании
$postMapper= new PostMapper($pdo);

// Создаем объект-пост
$post = new Post( );
$post->setTitle('Один день Ивана Ивановича');
$post->setText(...);

// сохраняем в базу
$postMapper->save($post);

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

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

Вот пример плохого класса:

// Сначала надо вызвать Connect иначе он не сможет соединиться с БД
PostMapper::$pdo = $pdo;
PostMapper::connect( );

// Затем надо создать массив с информацией о посте
$postArray = array(
'title' => 'Один день Ивана Ивановича',
'text' => '....',
'author' => 'Anonymous'
);

// Массив надо обработать иначе пост вставится, но без текста
DataProcessor::processDataArray($postArray);

// Дата добавления передается в MySQL-формате
$_POST['added'] = '2015-01-01 12:00:00';

// Не забыть выставить имя таблицы, а то вставится комментарий вместо поста!
PostMapper::$tableName = 'posts_table';

// Подготавливаем SQL-запрос - не забыть что тут нестатический метод
$postMapper= new PostMapper( );
$postMapper->prepareQuery( );

// делаем вставку в базу данных c помощью отдельного класса (каждый должен заниматься своим делом!)
SomeOtherClass::insertIntoDatabase( );

Вот как-то так. Надеюсь, что примеры дадут хотя бы немного понимания, как надо и как не надо писать. Если что-то тут непонятно или кажется неправильным, так и пиши.
#25 #432350
>>432118

В твоем случае надо:

- закрыть все публичные свойства в классе Thumbnail и удалить лишние
- закрыть все методы которые не требуется вызывать снаружи
- сделать так, чтобы любой публичный метод можно было вызвать в любой момент. То есть мы можем сразу вызывать createThumbnail не вызывая перед этим никаких calculateImage, и все будет работать.
- перенести аргументы из конструктора в createThumbnail
#26 #432352
>>432118

Вот такого: «ты должен сначала вызвать метод A перед тем как вызывать метод B» — быть не должно в принципе. Ибо когда у тебя в программе 1000 классов и 10 000 методов, как ты будешь запоминать что надо перед чем вызывать?

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

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

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


Я хочу создать превьюшку. Я вижу метод createThumbnail который это делает (это понятно из его названия). Ага, он-то мне и нужен! Чтобы его вызвать, мне достаточно создать объект и вызвать метод:

$t = new Thumbnail(...);
$t->createThumbnail(...);

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

Зачем мне вызывать calculateImae если я не хочу ничего рассчитывать, а хочу просто создать превьюшку?

Если вызов calculateImage необходим для createThumbnail, пусть они сами друг друга там вызывают. Зачем эту работу перекладывать на меня? Я хочу просто написать 2 строчки и чтобы все работало само.
#27 #432353
>>432118

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


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

> код должен быть понятным


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

А твой код как раз неочевиден: догадаться что надо сначала вызвать calculateIamge без полного разбора кода невозможно.

> Как она сломает код рано или поздно? Что от количества генераций превью будет метятся код?


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

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


Правильно.

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


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

Давай для начала попробуем хотя бы правильно написать класс генерации превьюшки или какой-то другой класс.
#28 #432356
>>432333

Введи в поиске на frilansim или на fl.ru в поиск «php» и там будет куча заданий.
#29 #432357
>>432356
Там все либо на фреймворках, либо вообще на кмс (за каким хером вы ищите програмиста и юзаете кмс?). А мелкие задания если и попадаются, их выставляют только для бизнес аккаунтов (нахуя?)
#30 #432358
>>432059
Вам тут оп распинается про DI и классы-заглушки, а вы не читаете что ли?
#31 #432360
>>432357

Потому что сайты пишут на фреймворках и CMS. B соответственно без их знания или желания разобраться 95% заказов тебе недоступны. На «чистом» PHP решают только разве что задачки про считалку из моего учебника, а сайты делают на HTML/CSS/JS и готовых библиотеках.

Но все равно, найти можно. По моему ты просто ленишься. Вот что я нашел без CMS и фреймворков.

> Написать простой скрипт , записи значения в базу и отправки на емейл. PHP + MYSQL


> Необходимо написать 100 текстов объявлений о продаже элитных квартир, каждое длиной в 500-600 знаков (с пробелами).


> Требуется удаленный контент-менеджер для занесения товаров на сайт интернет-магазина.


> Нужен Java (ох лол)-программист, несложный скрипт или jQuery. Должны поочередно подсвечиваться иконки,....


> Итак, есть одностраничный сайт – нужно сделать копию его функционала 1:1. Дизайн можно взять с сайта донора. Уверен что спецу работа на 1 день (ох лол)


> прикрутить плагин загрузки файлов jQuery File Upload на сайт


> Нужно доделать анкету на сайте new.fastmoney.ru new.fastmoney.ru/anketa/s... – при выборе "Адрес проживания совпадает с адресом регистрации?...


> Провести адаптивную модернизацию сайта rybhoz-civilsk.ru/


> Написать на php простой (ох лол) биллинг. Необходимо регистрация, регистрация через соцсети, прием оплат через робокассу и история оплат.


> Вывод папок и файлов на странице с помощью PHP


> подредактировать php скрипт – задача на 5-10 минут.


> Нужно создать или реализовать на готовом скрипте сервис сокращения ссылок


> Создать шапку для сайта


> Необходимо написать скрипт на PHP для работы с изображениями (картинками



Это то что я на первых 3 страницах нашел. Если ты это сам не смог найти то сначала тебе надо изучить работу функции поиска на фриланс-сайтах. Потмоу что с таким подходом ты далеко не уйдешь.

Хотя если кто-то из анонов хочет, пусть скидывает примеры заданий. Почему бы и нет. Но они вряд ли будут отличаться от того что написано выше.
#32 #432362
>>432357

Кстати, наш тред тебе поможет изучить CMS и фреймворки, если есть время и желание.
#33 #432363
>>432360
Сколько из этих заданий доступны без бизнес(или премиум) аккаунта?
#34 #432364
>>432363

Не знаю. А что это меняет? Тебе сложно найти подходящие задачи из-за низкого уровня знаний в первую очередь, так как таких, как ты, там сто тысяч человек, и все они конкурируют за эти несколько заданий.
#35 #432365
>>432360
Понял все лолы кроме биллинга. Это типа не такая уж простая задач, требующая в том числе согласования с конторой, предоставляющей такие услуги?
#36 #432368
>>432365

Вряд ли он такой простой. Там дальше еще какие-то фичи были перечислены.
#37 #432373
Скорее всего, у меня очень глупый вопрос, но как подключить yandex api для почты? Я делегировал домен на яндекс, вставляю код из документации в скрипт, но нихуя не работает, "Parse error: syntax error, unexpected 'Host' (T_STRING) in %путь к скрипту% on line 3". Халп.
#38 #432374
>>432373
Переводить текст ошибки не пробовал?
someApprentice #39 #432375
Господи... Не в тот тред написал =_______="
someApprentice #40 #432376
Создал "дирижера" методов.
https://github.com/someApprentice/ThumbnailService

Решил перенести некоторые методы из Upload в новый класс Functions (не знаю как правильно назвать чтобы понятно было, но там будут писаться полезные функции такие как например, генерация хэша изображения или создание директории). Все методы вызываются статически т.к, мне показалось что $functions = new Functions; как-то не совсем понятно. В общем хотелось бы услышать твои замечания по этому поводу.

Про остальные замечания, которые ты писал выше, я не забыл, и сделаю их, как разберусь с архитектурой, и вообще с моим пониманием ООП надо что-то делать.
someApprentice #41 #432377
Заранее извиняюсь за свою мясорубку программной мысли.
#42 #432386
>>432376

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


Мелкие, не относящиеся к чему-то конкетному методы обычно собирают в класс Util или Utility со всеми статическими методами.

http://en.wikipedia.org/wiki/Utility_pattern

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

> моим пониманием ООП надо что-то делать.


задачки решать наверно?
#43 #432389
>>432376

ImageManager лучше сделать на нестатических методах. static методы используют только в редких случаях вроде паттерна Utility или методов которым не нужен экземляр объекта.

Непонятно зачем нужен вообще класс Upload? Что он делает? Не проще ли метод uploadFile тогда перенести в ImaeManager? Или наоборот, всю работу с файлами и папками перенести в Upload?

Сейчас у тебя работа с файлами и папками для загуженных файлов (создание папок, определение пути к файлу, проверка типа файла, сохранение файла) фактически размазана по 3 классам: Upload, Functions, ImageManager. Надо собрать все в одном месте.

> $connect = Connect::getPdo( );


Это надо убрать и передавать PDO через конструктор.

> https://github.com/someApprentice/ThumbnailService/blob/master/Classes/Database.php#L88


> return $insert;


зачем возвращать объект PDO Statement? Что с ним можно потом сделать?

> public static function uploadFile($name, $temp, $extension) {


Непонятно зачем передавать отдельным параметром extension. Мы же всегда его можем получить из name?

> "uploads/" . $directory . '/' . $name


Этот кусок скопипащен раз 5. Сделай лучше метод типа getImagePath() который возвращает полный путь к файлу.

> https://github.com/someApprentice/ThumbnailService/blob/master/Classes/Functions.php#L28


> public static function getExtension($name) {


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

> https://github.com/someApprentice/ThumbnailService/blob/master/Classes/ImageManager.php#L30


> unlink("uploads/" . $name);


ты сохраняешь файл в "uploads/" . $directory . '/' . $name а удаляешь из другого места. Не надо копиастить код, надо хранить путь в переменной.
#43 #432389
>>432376

ImageManager лучше сделать на нестатических методах. static методы используют только в редких случаях вроде паттерна Utility или методов которым не нужен экземляр объекта.

Непонятно зачем нужен вообще класс Upload? Что он делает? Не проще ли метод uploadFile тогда перенести в ImaeManager? Или наоборот, всю работу с файлами и папками перенести в Upload?

Сейчас у тебя работа с файлами и папками для загуженных файлов (создание папок, определение пути к файлу, проверка типа файла, сохранение файла) фактически размазана по 3 классам: Upload, Functions, ImageManager. Надо собрать все в одном месте.

> $connect = Connect::getPdo( );


Это надо убрать и передавать PDO через конструктор.

> https://github.com/someApprentice/ThumbnailService/blob/master/Classes/Database.php#L88


> return $insert;


зачем возвращать объект PDO Statement? Что с ним можно потом сделать?

> public static function uploadFile($name, $temp, $extension) {


Непонятно зачем передавать отдельным параметром extension. Мы же всегда его можем получить из name?

> "uploads/" . $directory . '/' . $name


Этот кусок скопипащен раз 5. Сделай лучше метод типа getImagePath() который возвращает полный путь к файлу.

> https://github.com/someApprentice/ThumbnailService/blob/master/Classes/Functions.php#L28


> public static function getExtension($name) {


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

> https://github.com/someApprentice/ThumbnailService/blob/master/Classes/ImageManager.php#L30


> unlink("uploads/" . $name);


ты сохраняешь файл в "uploads/" . $directory . '/' . $name а удаляешь из другого места. Не надо копиастить код, надо хранить путь в переменной.
#44 #432390
>>432377

Это учебный тред, так что все ок.
#45 #432392
>>432376

>


> <?php


> require_once 'autoload.php'


> ?>


Это должно быть только в файлах типа index.php а не скопипащено в каждыйы файл с классом.
#46 #432393
>>432376

> https://github.com/someApprentice/ThumbnailService/blob/master/upload.php#L38


> if (($thumbnailWidth != '' xor $thumbnailHeight != '') or ($thumbnailWidth != '' and $thumbnailHeight != '')) {



Не используй xor в лонгических условиях (слишком сложно) и упрости этот код. Что ты хотел сказать? Если хотя бы один параметр указан? Тогда тебе хватит OR.
#47 #432416
Никак не могу решить задачку с телефонами раздел "регулярные выражения" из нубо-учебника. Дайте хоть подсказочку.
#48 #432435
>>432416

Покажи код. Для начала можешь сделать упрощенную версию: номер телефона всегда начинается только с цифры 8 после которой идет 9 любых цифр без минусов, скобок , и т.д.
631 Кб, 1916x537
#49 #432438
у меня есть 3 слайдшоу которые в ширину располагаются как пикрелейтед таким образом
position: absolute;
left: 17px;
width: 32.5%;
При изменении ширины окна изменяется высота этих слайдшоу(так они помещаются на странице в любом случае). Как в условии плавающей высоты отцентрировать их по вертикали?
#50 #432440
>>432438
https://ideone.com/KLmbkj
вот css всех трех
#51 #432443
>>432438
>>432440
Заливай на jsbin например вместе с разметкой. Вместо пикч бери placehold.it
И зачем ты их ставишь абсолютно все?
#52 #432466
>>432324
Нет, не оплачивают. Просто на предыдущей работе я занимался проектом, и хотел в портфолио его выложить как следует, с полным кодом фронтенда. Кода там довольно много, как раз хороший пример, что работал над не совсем маленьким проектом. Ну и без данных там весь функционал пропадает, довольно плохо получится.
Да сделать просто json файлы кажется адекватной идеей, скорее всего так и поступлю.
#53 #432474
>>432435
Это то я могу. Вот именно скобки и прочие тире меня в тупик ставят.
#54 #432475
>>432474

Тогда сделай чуть сложнее: между цифрами может быть любое число скобок, дефисов, пробелов. Это подойдет для задачи.
#55 #432478
>>432475
По моему я переборщил, да?
'/^8([(- ][0-9]{3}[(- ][0-9]{3}[(- ][0-9]{2}[(- ][0-9]{2}[(- ]*)$/'
#56 #432479
>>432478
Черт, вакаба звездочки съела.
В общем, вот.
http://ideone.com/8j1wuG
#57 #432481
>>432479

У тебя же ошибка: PHP Warning: preg_match(): Compilation failed: range out of order in character class at offset 6 in /home/kpQzwB/prog.php on line 8

Минус это спецсимвол внутри квадратных скобок и надо его экранировать.

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

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

Вот список номеров:

Правильные: array('84951234567', '+74951234567', '8-495-1-234-567', ' 8 (8122) 56-56-56', '8-911-1234567', '8 (911) 12 345 67', '8-911 12 345 67', '8 (911) - 123 - 45 - 67', '+ 7 999 123 4567', '8 ( 999 ) 1234567', '8 999 123 4567');

Неправильные: array('02', '84951234567 позвать люсю', '849512345', '849512345678',
'8 (409) 123-123-123', '7900123467', '5005005001', '8888-8888-88',
'84951a234567', '8495123456a',
'+1 234 5678901', // неверный код страны
'+8 234 5678901', // либо 8 либо +7
'7 234 5678901' // нет +
);
20 Кб, 617x192
#58 #432514
здравствуй программач! ребят , вот я прочитал статью на вике про MVC , там есть пример кода для каждого блока, можете подсказать как их правильно разместить чтобы протестировать? Вот я закидываю их в директорию которую у меня слушает апач, создаю там папки models , views и controllers , в каждом index.php . как лучше протестировать работоспособность?
#59 #432516
>>432514
Скачай себе какой-нибудь микрофреймворк. Slim, для примера. И разбирайся уже на нем.
Аноним #60 #432539
Привет, в общем следующий вопрос:
Лепил дерьмо на пхп с 14 лет, в общем нужно восстановить свои навыки. Синтаксис и прочее я знаю, имею ввиду наработать практические навыки.
#61 #432541
>>432539
Ну нарабатывай, даю добро. Потом отчитаешься здесь за проделанную работу.
Аноним #62 #432545
>>432541
Какие ваши советы, материал для изучения?
#63 #432548
>>432545
В оп-пост гляди. Открываешь учебник ОПа и смотришь какие задачи можешь выполнить, а в каких не уверен.
4 Кб, 100x100
#64 #432555
ОП, знаю ты всегда можешь дать годных советов по улучшению кода.

Не глянешь вот это?:
https://github.com/d-beekeeper/ratchat

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

Там в Readme описание, что это такое и как работает.

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

Кстати если подскажешь какую нибудь готовую oAuth библиотеку для Silex-Symphony (или вообще универсальную) для однообразной авторизации юзера через кучу разных соцсетей - буду очень благодарен.

Заранее спасибо.
#65 #432568
Добрый день, снова я с задачкой на графы.
http://ideone.com/mWiW77
Выдает кучу ошибок которые тем не менее не мешают отобразить в конце верный результат. Ошибки на сколько я понял связаны с тем что не во всех циклах $newPath['time'] существует, но как пофиксить не понял.
#66 #432604
пацаны, как сделать ссылку на локальную папку
в гугле советуют делать так
<a href="file:///C:/Windows">Открыть диск C:/Windows</a>
а у меня такое не работает.
#67 #432618
Вопрос у эпического нюфани. Есть БД mysql, есть сайт, который ведет поиск по базе данных и выводит инфу о человеке: Имя, Фамилия, Информация о нем. Как сделать так, чтобы поле информации было редактируемое? То есть нашел человека, вписал в поле, сохранилось. И в следующий раз при поиске я получаю то что написал для каждого отдельно. Устал гуглить, не бейте, лучше обоссыте
#68 #432620
>>432618
input type="text". грубо говоря можно в форме отправляя запрос на скрипт. но тебе врядли. тебе лучше по аяксу на событие какое-то, типа изменения, сам решишь, точно так же будет ебать скриптик и сохранять. ну и еще вариант на каком-нибудь ангуларе, все свое на фронтенде сразу, если не ошибаюсь.
#69 #432623
>>432481
Я тупой. Как в регулярное выражение, скажем, '/^\\+?8?7?[0-9]{10}$/' добавить проверку знаков в это [0-9]?
sage #70 #432628
>>432623
Регулярки такого не поддерживают, тебе нужно вызывать хаскель, и уже там функцию определять.
#71 #432632
>>432628

>сажамен смпешит на помощ))))))

sage #72 #432634
>>432623
теория категорий
#73 #432635
>>432634

>я сажамен я спосу тебя))

56 Кб, 600x401
sage #74 #432636
#75 #432637
Люто проиграл с вашего диалога!
Может поможет кто?>>432623
35 Кб, 333x500
#76 #432645
>>432637
Прочитай пикрелейтед. Тебе нужны фундаментальные знания, а не жалкие всхлипы анонов про регекспы. И вообще каких знаков проверка-то? Есть дорожные знаки, а есть унарные отображения из множества R в R, типа + и -.
#77 #432649
Аноны, помогает ли ведение тетради по пройденному материалу в обучении? Или просто почитывать и практиковаться на задачках?
#78 #432653
>>432649
Помогает, было доказано учёными из Кэмбриджа. Только без фанатизма - самую писечку записывай, а потом повторяй время от времени. Сам факт записывания даёт больше всего профита. Ещё помогают mind maps, их лучше от руки рисовать, а потом можно в программу типа freemind перенести. Можешь личную вики запилить (я gollum использую, мне норм), тоже полезно пополнять. Лично я уже привык всё это использовать - без этого как-то не идёт обучение. Я ещё исходный код и API распечатываю на принтере и обклеиваю всю квартиру. Потом когда иду делать кофе, могу прочитать про какую-нибудь стандартную либу на стене, или паттерны там. Даже на потолок клею, лол. Ещё использую Anki для переодической ревизии своих знаний и сам с собой на английском говорю. Иногда по скайпу общаюсь ну ты понел. Про жизнь вообще забудь.
#79 #432658
Оп, а можно ли для отдельной части страницы использовать другую версию jquery, потому что плагины не совместимы?
с одной версией один работает, второй нет. с другой работает второй, а первый нет. Подключал jquery-migrate
и работают оба скрипта, но криво, короче не так как следует.
#80 #432660
>>432653

> Про жизнь вообще забудь.


Да у меня ее и нет.

>я gollum использую, мне норм


Gollum? Что это такое? Гугл ничего не дал.

Благодарю за помощь, анонче.
#81 #432665
+ >>432660
Допустим, я выписал функцию error_reporting (что делает, как работает). Мне нписанное тупо зубрить/представлять/с чем-то ассоциировать? Как у тебя это усваивается в голове?

Вопрос, конечно, тупой, но я никогда особо не обучал себя сам, потому спрашиваю.
#82 #432678
>>432653
А я пробовал и так и сяк. И вики пилить ,и просто записывать. Рукой в тетради лучший вариант. Пока записываешь запомнишь и поймешь больше, чем пока читал. Тру стори.
#83 #432700
>>431924
ОП ОП

проверь меня

https://github.com/tokotun/matriculant
#84 #432708
>>432700
упс, сохранить не могу.

Uncaught exception 'PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'sdfsdf@dfss.dgh' for key 'email'' in C:\localhost\www\matriculant\app\MatriculantMapper.php
#85 #432728
Посоны, как числа в строку засунуть?


<?php

error_reporting(-1);

$str[] = "";

for ($i = 0; $i < 5; $i++)
{
$numb = mt_rand(0, 9);
$str += $numb;
}
echo $str;
?>
#86 #432729
>>432728
там $str += $numb;

самофикс
#87 #432730
>>432728

$str .= $numb;
если я правильно тебя понял.
#88 #432731
>>432729
Блядь, $str[переменная i] += $numb;
#89 #432732
>>432730
Спасибо, попробую.
#90 #432738
class templater {
...
private $variables = array("title"=>"DEFAULT_TITLE");
...
public function set_var($name, $value){
$this->variables[$name] = $value;
}
...
}
...
$templater->set_var('url_path','http://'.$_SERVER['HTTP_HOST']);
$templater->set_var('rel',$templater->variables['url_path'].substr($templater->variables['path'],strlen(ROOT_DIR)));
...
echo $this->variables['url_path'] Выводит значение нормально
echo $this->variables['rel']; Не выводит вообще ничего!

Видимо вот здесь:
$templater->variables['url_path'].substr($templater->variables['path'],strlen(ROOT_DIR))
Кроется ошибка.

Какая?

Алсо, каким тегом в макабе оформлять код?
#91 #432739
>>432738
код лучше выкладывать на ideone
http://ideone.com/
#92 #432740
>>432739
Просто там много кода, раскиданного по разным *.php файлам, которые друг друга вызывают через require_once, поэтому будет нечитаемо, если в ideone выкладывать.
#93 #432742
>>432740
тогда на гитхаб
https://github.com/
#94 #432747
http://ideone.com/mPNguF
Вот и какого черта он мне на 7-ом и 2-ом ошибку выдаёт? Причем выдаёт постоянно, что бы я туда не подставил.
#95 #432766
>>432747
странно у меня не постоянно.
Возможно ты путаешь индексы в массиве. Массив начинается с 0 а не с 1.
Или возможно, когда ты подставляешь другое значение, у тебя остаётся лишний пробел в ячейке массива.
#96 #432771
>>432766
http://ideone.com/mPNguF
Вот так переделал. Все равно ошибка.
37 Кб, 778x419
#97 #432780
А можно к вам на рельсах и метеоре вкатиться? Спасибо. Сейчас начну делать первое задание, глядишь завтра будет что показать. Для код-ревью запощу на реддит или на рельсо-форум. Алсо, ОП, ты няша.
#98 #432783
>>432362
Я другой анон, но как раз хочу выучить и кмс и фреймворки, обычное пхп, вроде бы не определённом уровне знаю. На уровне написания небольшого интернет-магазина с типичным функционалом. Я вот только никак не могу понять как вообще учить фреймворки и КМС, если по фреймворкам я ещё находил кое-какие руководства, то по КМС вообще непонятно.
#99 #432785
>>432783
Что мешало найти руководства по CMS?
#100 #432937
>>432785
Я всегда нахожу руководства как для контент-манаджера, не могу ничего найти с точки зрения ПХП. Кто как учил КМС и Фреймворки, может поделиться опытом?
#101 #432972
>>432937
Доки же. Для cms тоже должны быть. В крайнем случае ищи видеогайды по своей cms, статьи на хабре или еще где, вот это все. Всегда можно найти как залезть поглубже в это говно. Хуево ищешь короче.
#102 #432984
>>432568
бамп
#103 #432999
Чому это дело не компилируется?
#104 #433000
>>432999
http://ideone.com/5oyfFZ
Дело забыл.
Выдает ошибку

> preg_split(): Compilation failed: missing ) at offset 234 in /home/kkWr5I/prog.php on line 8

sage #105 #433003
>>433000

> missing )


рнршка соскучилась за скобкой))((
#106 #433098
>>432937
google: %cms_name% development guide
#107 #433099
>>432999
Томущо ты не читаешь текст ошибки
MindiMakridi #108 #433130
Я тут посмотрел твой код. Надеюсь, что ты не тратил это время зря, а уже потихоньку начала делать следующее задание.

Все бы хорошо, но у тебя там XSRF неисправленная. Разумеется оставлять код с уязвимостями никак нельзя.

У тебя по-прежнему есть XSRF. Ты наверно не понимаешь, как она работает (или забыл ее исправить). Давай я покажу, как ее использовать.

Зайди на свой сайт, зарегистрируйся (чтобы создались куки и ты был авторизован). Затем создай и помести на любой сайт (можно на тот же самый) файл xsrf.html с таким содержимым (проверь что в action стоит правильный адрес): http://ideone.com/qJy0dX

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

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

Надо это исправить, добавив в форму код и проверяя его на совпадение с кодом из кук.

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

В будущем бороться с XSRF станет легко так как новые браузеры уже посылают при любом запросе заголовок Origin: http://example.com/ который указывает с какого домена отправлена форма, и можно будет автоматически на уровне сервера отвергать любые POST запросы с чужих доменов. Но пока надо использовать токены.

> $report = "Изменения сохранены";


> header("Location: http://students.ru/profile.php?msg=$report");


Вообще, лучше использовать условные коды-обозначения например registered, или числа (для них в коде разумеется надо сделать константы), а не сам текст. А то появляется простор для мошенничества, например злоумышленник может подставить какой-нибудь свой текст на страницу («Внесите X руб. на мой счет для продолжения регистрации»).

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

> https://github.com/MindiMakridi/Students/blob/master/index.php#L103


> $link = htmlspecialchars($currentPage) . "?order=" .


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

htmlspecialchars($currentPage . "?order=" . $sort. "&direction=" .... )

> https://github.com/MindiMakridi/Students/blob/master/templates/main.html#L29


> <a href=<?= $link ?>&amp;num=<?= $i * $recordsPerPage ?>><?= $i + 1 ?>


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

> https://github.com/MindiMakridi/Students/blob/master/profile.php#L34


> else {


Почему перед else несколько пустых строк? Создается ощущение что он тут вообще идет как отедльная команда и сам по себе. if/else пишется так:

if () {
...
} else {
...
}

> https://github.com/MindiMakridi/Students/blob/master/lib/functions.php#L20


> return $code = $_COOKIE['studentscookie']['code'];


зачем в одной строке совмещать создание переменной и return? Это 2 отдельных команды и лучше писать так:

$code = $_COOKIE['studentscookie']['code'];
return $code;

А еще лучше вообще не создавать тут переменную:

return $_COOKIE['studentscookie']['code'];

Ну и вообще, если у тебя есть где-то присваивание вида $x = ... то оно должно идти отдельной строкой, а не быть внутри другой команды (исключение — for, там можно так делать). Если прятать присваивание внутри других команд, его становится труднее заметить. А в данной ситуации переменная вообще не нужна так как никогда не используется.

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

Все бы хорошо, но у тебя там XSRF неисправленная. Разумеется оставлять код с уязвимостями никак нельзя.

У тебя по-прежнему есть XSRF. Ты наверно не понимаешь, как она работает (или забыл ее исправить). Давай я покажу, как ее использовать.

Зайди на свой сайт, зарегистрируйся (чтобы создались куки и ты был авторизован). Затем создай и помести на любой сайт (можно на тот же самый) файл xsrf.html с таким содержимым (проверь что в action стоит правильный адрес): http://ideone.com/qJy0dX

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

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

Надо это исправить, добавив в форму код и проверяя его на совпадение с кодом из кук.

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

В будущем бороться с XSRF станет легко так как новые браузеры уже посылают при любом запросе заголовок Origin: http://example.com/ который указывает с какого домена отправлена форма, и можно будет автоматически на уровне сервера отвергать любые POST запросы с чужих доменов. Но пока надо использовать токены.

> $report = "Изменения сохранены";


> header("Location: http://students.ru/profile.php?msg=$report");


Вообще, лучше использовать условные коды-обозначения например registered, или числа (для них в коде разумеется надо сделать константы), а не сам текст. А то появляется простор для мошенничества, например злоумышленник может подставить какой-нибудь свой текст на страницу («Внесите X руб. на мой счет для продолжения регистрации»).

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

> https://github.com/MindiMakridi/Students/blob/master/index.php#L103


> $link = htmlspecialchars($currentPage) . "?order=" .


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

htmlspecialchars($currentPage . "?order=" . $sort. "&direction=" .... )

> https://github.com/MindiMakridi/Students/blob/master/templates/main.html#L29


> <a href=<?= $link ?>&amp;num=<?= $i * $recordsPerPage ?>><?= $i + 1 ?>


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

> https://github.com/MindiMakridi/Students/blob/master/profile.php#L34


> else {


Почему перед else несколько пустых строк? Создается ощущение что он тут вообще идет как отедльная команда и сам по себе. if/else пишется так:

if () {
...
} else {
...
}

> https://github.com/MindiMakridi/Students/blob/master/lib/functions.php#L20


> return $code = $_COOKIE['studentscookie']['code'];


зачем в одной строке совмещать создание переменной и return? Это 2 отдельных команды и лучше писать так:

$code = $_COOKIE['studentscookie']['code'];
return $code;

А еще лучше вообще не создавать тут переменную:

return $_COOKIE['studentscookie']['code'];

Ну и вообще, если у тебя есть где-то присваивание вида $x = ... то оно должно идти отдельной строкой, а не быть внутри другой команды (исключение — for, там можно так делать). Если прятать присваивание внутри других команд, его становится труднее заметить. А в данной ситуации переменная вообще не нужна так как никогда не используется.

В общем, из ошибок только XSRF, и несколько мелких замечаний к коду.
#109 #433140
ОП, ньюфаг невероятно горд собой, и благодарит тебя. Мне удались первая и вторая часть задачек с телефонами и регулярными выражениями! Вуху!
http://ideone.com/VMAre5
Tokotun #110 #433153
>>432023

Я вижу, ты код красивее оформил? Это хорошо, читать стало чуть удобнее. И публичные свойства убрал. Совсем хорошо. Если что, для геттеров/сеттеров во многих редакторах есть сниппеты (либо их можно нагуглить), которые позволяют их быстро создавать. Вот например мой сниппет для Sublime 3: https://gist.github.com/codedokode/cd2f41c8dcf1237fde4b

Еще геттеры/сеттеры можно не создавать, а использовать магические методы get/set ( http://php.net/manual/ru/language.oop5.overloading.php#object.get ), но они сильно усложняют понимание кода, и в учебной задаче наверно не стоит их использовать.

Для начала, по архитектуре замечание. Паттерн «data mapper» подразумевает, что для работы с базой данных мы создаем классы, по одному на каждую таблицу, и только эти классы могут напрямую работать с базой, причем каждый в первую очередь со своей таблицей (но может использовать другие таблицы в запросах, для джойнов например). SQL кода в других класах быть не должно. А что у тебя?

> https://github.com/tokotun/matriculant/blob/master/app/Template.php#L14


Твой класс template не должен лезть в базу. Он должен вызывать для этого методы MatriculantMapper (ну и на всякий случай напомню что в свою очередь класс Data Mapper не должен лезть в POST, COOKIE, что либо выводить на экран).

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

Вообще, если очень хочется, можно сделать класс который в полях хранит переменные для шаблона. Такой класс принято называть ViewModel или PageModel. Но тогда ты должен передавать все переменные только через него (а не половину напрямую, а половину через класс) и для каждого шаблона нужен свой класс ViewModel так как они используют разный набор переменных. По моему, в этой простой задаче проще передавать переменые напрямую, но если тебе хочется заморочиться, можешь сделать классы. Классы типа ViewModel обычно делают для использования в яваскрипте вместе с data binding (если будешь изучать Knockout или Angular, узнаешь что это за байндинг), а на стороне PHP не используются.

> https://github.com/tokotun/matriculant/blob/master/app/MatriculantMapper.php#L37


> print_r($matriculant);


Отладочный код не удалил. Полезно перед коммитом делать git diff (или, что удобнее, аналогичную команду в GUI утилите для работы с git) и кратко просматривать что коммитишь.

> https://github.com/tokotun/matriculant/blob/master/app/MatriculantMapper.php#L13


> protected function bindField($statment,


Тут для statement стоит указать класс PDOSTatement.

> https://github.com/tokotun/matriculant/commit/06d18822dd9afc3fa6519c0e0a2636559bb6fc70#diff-0


> ингорировать файлы в папке boostrap


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

> https://github.com/tokotun/matriculant/blob/master/templates/header.php#L13


> <?php if ($_SERVER['PHP_SELF'] == '/matriculant/index.php'):


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

Аналогично тут

> https://github.com/tokotun/matriculant/blob/master/templates/profile.php#L10


> if ($_GET['action'] == 'update'):?>


Лучше бы не лезть в GET а использовать переменную, а в GET лезть в login.php

> setcookie('id', $matriculant->getId(), strtotime('+10 year'), null, null, false, true);


У кук есть интересный параметр path. Он определяет, на каких страницах должна быть доступна кука и по умолчанию он равен адресу той страницы где она выставляется. Если его явно не выставлять в '/' то возможны интересные труднообнаружимые баги: например, кука выставляемая страницей /user/login.php не будет передаваться на страницу /index.php. Почитай про куки:

http://citforum.ru/internet/html/cookie.shtml (очень древняя статья, зато на русском)
http://en.wikipedia.org/wiki/HTTP_cookie#Domain_and_Path (англ)

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

> https://github.com/tokotun/matriculant/blob/master/app/MatriculantMapper.php#L77


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

https://ru.wikipedia.org/wiki/PHPDoc
http://habrahabr.ru/post/162535/

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

> https://github.com/tokotun/matriculant/blob/master/app/MatriculantMapper.php#L83


> foreach ($columns as $keyColumn => $valueColumn)


Используй array_keys (заодно почитай какие вообще есть функции работы с массивами: http://php.net/manual/ru/ref.array.php ). Алсо, не пиши foreach в одну строку, после скобки { надо делать перенос строки.

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

Более того, передавать список извне еще и менее безопасно, так как непонятно, глядя на код функции, откуда приходит этот список и можно ли ему доверять. Лучше все же вписать список прямо в функцию или сделать метод у MMapper вроде getAllowedSortColumns.

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

XSS в поиске вроде нет — я проверил вводом волшебной комбинации <b>>"'&copy; (при наличии XSS часть символов не отобразится либо вставится в виде HTML кода). Только наверно стоит при поиске в поле поиска тоже подставлять введенный текст.

В общем, я думаю, все уже практически сделано, остается только исправить мелкие замечания. Будешь дальше файлообменник делать? С использованием Slim, Twig (кстати с ним тебе не придется писать htmlspecialchars так как там есть автоескейпинг).
Tokotun #110 #433153
>>432023

Я вижу, ты код красивее оформил? Это хорошо, читать стало чуть удобнее. И публичные свойства убрал. Совсем хорошо. Если что, для геттеров/сеттеров во многих редакторах есть сниппеты (либо их можно нагуглить), которые позволяют их быстро создавать. Вот например мой сниппет для Sublime 3: https://gist.github.com/codedokode/cd2f41c8dcf1237fde4b

Еще геттеры/сеттеры можно не создавать, а использовать магические методы get/set ( http://php.net/manual/ru/language.oop5.overloading.php#object.get ), но они сильно усложняют понимание кода, и в учебной задаче наверно не стоит их использовать.

Для начала, по архитектуре замечание. Паттерн «data mapper» подразумевает, что для работы с базой данных мы создаем классы, по одному на каждую таблицу, и только эти классы могут напрямую работать с базой, причем каждый в первую очередь со своей таблицей (но может использовать другие таблицы в запросах, для джойнов например). SQL кода в других класах быть не должно. А что у тебя?

> https://github.com/tokotun/matriculant/blob/master/app/Template.php#L14


Твой класс template не должен лезть в базу. Он должен вызывать для этого методы MatriculantMapper (ну и на всякий случай напомню что в свою очередь класс Data Mapper не должен лезть в POST, COOKIE, что либо выводить на экран).

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

Вообще, если очень хочется, можно сделать класс который в полях хранит переменные для шаблона. Такой класс принято называть ViewModel или PageModel. Но тогда ты должен передавать все переменные только через него (а не половину напрямую, а половину через класс) и для каждого шаблона нужен свой класс ViewModel так как они используют разный набор переменных. По моему, в этой простой задаче проще передавать переменые напрямую, но если тебе хочется заморочиться, можешь сделать классы. Классы типа ViewModel обычно делают для использования в яваскрипте вместе с data binding (если будешь изучать Knockout или Angular, узнаешь что это за байндинг), а на стороне PHP не используются.

> https://github.com/tokotun/matriculant/blob/master/app/MatriculantMapper.php#L37


> print_r($matriculant);


Отладочный код не удалил. Полезно перед коммитом делать git diff (или, что удобнее, аналогичную команду в GUI утилите для работы с git) и кратко просматривать что коммитишь.

> https://github.com/tokotun/matriculant/blob/master/app/MatriculantMapper.php#L13


> protected function bindField($statment,


Тут для statement стоит указать класс PDOSTatement.

> https://github.com/tokotun/matriculant/commit/06d18822dd9afc3fa6519c0e0a2636559bb6fc70#diff-0


> ингорировать файлы в папке boostrap


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

> https://github.com/tokotun/matriculant/blob/master/templates/header.php#L13


> <?php if ($_SERVER['PHP_SELF'] == '/matriculant/index.php'):


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

Аналогично тут

> https://github.com/tokotun/matriculant/blob/master/templates/profile.php#L10


> if ($_GET['action'] == 'update'):?>


Лучше бы не лезть в GET а использовать переменную, а в GET лезть в login.php

> setcookie('id', $matriculant->getId(), strtotime('+10 year'), null, null, false, true);


У кук есть интересный параметр path. Он определяет, на каких страницах должна быть доступна кука и по умолчанию он равен адресу той страницы где она выставляется. Если его явно не выставлять в '/' то возможны интересные труднообнаружимые баги: например, кука выставляемая страницей /user/login.php не будет передаваться на страницу /index.php. Почитай про куки:

http://citforum.ru/internet/html/cookie.shtml (очень древняя статья, зато на русском)
http://en.wikipedia.org/wiki/HTTP_cookie#Domain_and_Path (англ)

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

> https://github.com/tokotun/matriculant/blob/master/app/MatriculantMapper.php#L77


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

https://ru.wikipedia.org/wiki/PHPDoc
http://habrahabr.ru/post/162535/

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

> https://github.com/tokotun/matriculant/blob/master/app/MatriculantMapper.php#L83


> foreach ($columns as $keyColumn => $valueColumn)


Используй array_keys (заодно почитай какие вообще есть функции работы с массивами: http://php.net/manual/ru/ref.array.php ). Алсо, не пиши foreach в одну строку, после скобки { надо делать перенос строки.

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

Более того, передавать список извне еще и менее безопасно, так как непонятно, глядя на код функции, откуда приходит этот список и можно ли ему доверять. Лучше все же вписать список прямо в функцию или сделать метод у MMapper вроде getAllowedSortColumns.

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

XSS в поиске вроде нет — я проверил вводом волшебной комбинации <b>>"'&copy; (при наличии XSS часть символов не отобразится либо вставится в виде HTML кода). Только наверно стоит при поиске в поле поиска тоже подставлять введенный текст.

В общем, я думаю, все уже практически сделано, остается только исправить мелкие замечания. Будешь дальше файлообменник делать? С использованием Slim, Twig (кстати с ним тебе не придется писать htmlspecialchars так как там есть автоескейпинг).
#111 #433172
Няши, поясните за API. Что-то не слишком понимаю, как формируется запрос. Вот документация. Как это должно выглядеть в финальном скрипте?
https://tech.yandex.ru/pdd/doc/reference/email-ml-add-docpage/
C меня лучи добра!
#112 #433184
>>433172

POST запросы из скрипта делаются с помошью CURL. Ему просто массив параметров передаешь, он сам тело запроса формирует
#113 #433189
Взялся за решение задач после долгого перерыва. вот накидал функцию для одного шага из поиска пути. Гляньте, норм ли всё или как?
http://ideone.com/WepQw3
127 Кб, 617x886
#114 #433190
Анончики, какие минимальные знания нужны, чтоб устроиться стажером?
И сколько обычно стажировка идёт?
Алсо там что-то вроде "базовых знаний" по php и mysql.
Базовые, это какие?
PHP вот курсик ОПа допрохожу, сегодня начал читать пикрелейтед, вроде неплохо подано, но, если я не ебусь в глаза, практических заданий там нет особо.
По MySQL у меня знания нулевые, на данный момент.
Ньюфаг, не гоните плз.
#115 #433191
>>433184
Спасибо!
#116 #433195
>>433172

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

В PHP встроено расширение curl, но оно довольно низкоуровневоее и неудобное. Удоюнее пользоваться сторонней библиотекой, например Guzzle. Почитай ее мануал или погугли «как отправить POST запрос с помощью Guzzle»

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

https://ru.wikipedia.org/wiki/HTTP
http://habrahabr.ru/post/215117/

HTTP относительно простой протокол. Ты можешь сам увидеть какие запросы шлет твой браузер, открыв инспектор на любом сайте (Ctrl + Shift + I) на вкладке Network, и покликать по ссылкам.
#117 #433197
>>432568
я тону :<
#118 #433198
>>433190

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

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

> Базовые, это какие?


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

По MySQL, не базовый, а полный список того что хорошо бы знать, перечислем тут: https://gist.github.com/codedokode/10539213#%D0%9D%D0%B0-%D1%87%D1%82%D0%BE-%D1%81%D1%82%D0%BE%D0%B8%D1%82-%D0%BE%D0%B1%D1%80%D0%B0%D1%82%D0%B8%D1%82%D1%8C-%D0%B2%D0%BD%D0%B8%D0%BC%D0%B0%D0%BD%D0%B8%D0%B5

Это может напугать начинающего, но реально там неделя-две максимум изучать, а знания будут хорошие. В реальности часто требуется меньше знаний, но лучше переучить чем недоучить, верно?
#119 #433199
>>433190

> И сколько обычно стажировка идёт?


2-3 месяца, но в сытые годы высокой цены на нефть в Москве брали всех подряд и стажировали по полгода.
#120 #433204
>>433198
Вышел новый никсон, в интернетах есть или нет не знаю, но на русский точно переведен. Впрочем, там также рассказывается например про mysqli а не про PDO, так что непонятно.
#121 #433205
>>432740

А если ты пока не осилил гит и гитхаб (хотя в ОП посте есть ссылка на git book на русском языке), то можешь открыть gist.github.com и постить туда. Он поддерживает добавление файлов перетаскиванием на страницу.
#122 #433209
>>433195
Спасибо огромное, дальше, я думаю, сам справлюсь. Очень хорошо все расписал. Добра тебе!
#123 #433212
>>432738

Анон, прежде чем продолжать делать без сомнения интересный и инновационный проект Templater, прочти пункт 6 из этой статьи (остальные тоже не помешает прочесть): http://habrahabr.ru/post/230737/
#124 #433214
>>433204

Повторю еще раз про mysqli. Действительно, в PHP сейчас есть 2 актуальных библиотеки для работы с БД: PDO и mysqli. PDO более известная и раскрученная, хотя если срого сравнивать, фич в mysqli больше (но с другой стороны там нет исключений при ошибках).

Но многие сайты, учебники выбирают mysqli не из-за фич. Они выбирают ее потому что она поддерживает функции, аналогичные устаревшей mysql, которые достаточно чуть переименовать: mysql_query -> mysqli_query

Это значит что если ты видишь использование mysqli на функциях вроде mysql_query, 99% что перед тобой устаревший материал 10-летней давности в котором просто приписали буковку i (и может быть до сих пор вставляют переменные в текст запроса). Подумай, стоит ли читать про допотопный подход без использования ООП?

Или лучше прочесть более современную статью про вроде этих:

- про PDO: http://habrahabr.ru/post/137664/
- про MySQLi c ООП-подходом: http://habrahabr.ru/post/141127/
#125 #433243
>>432514

> Вот я закидываю их в директорию которую у меня слушает апач, создаю там папки models , views и controllers , в каждом index.php


Ты что-то перепутал. Напрямую ты обращаешься либо к скрипту-контроллеру (например /index.php, /register.php) либо вообще у тебя все обращения идут на один скрипт index.php а он уже определяет какой контроллер вызвать. А к моделям и шаблонам ты из браузера не обращаешься напрямую. Их подключает контроллер.

Почитай например эту статью:

- http://habrahabr.ru/post/150267/ (тут дана не совсем правильная картинка MVC, там приведена картинка MVC для десктопных GUI приложений, а не для сайтов, также используются статические методы)

Заметь что в статье используется ООП. Конечно, сам по себе принцип MVC не требует исплоьзования ООП, но на практиве все MVC фреймворки обычно его (ООП) используют.

После статьи советую изучить фреймворк Yii 2 — он тоже исплоьзует ООП.
#126 #433245
>>432539
>>432545

У меня есть такие вещи:

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

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

- дополнительные неплохие задачи на изучение HTML/CSS/JS/MySQL. они позволят увидеть какие места ты плохо знаешь и дать тебе ссылки и советы по изучению. В идеале хорошо бы их прорешать.

В общем, открой ОП-пост, посмотри что там есть и выбери что ты хочешь решать. Если у тебя есть какие-то вопросы, что-то непонятно, хочется проверить решение, нужна подсказка, пиши в тред, я отвечу.
#127 #433279
>>432555

Анон, я с удовольствием посмотрю, но уже не сегодня. Сегодня я успел только полистать документацию по reactphp, ratchet и еще чему-то, а код посмотреть лшь мельком. Но я проверю позже, штука интересная.

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

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

Я сужу вот по этому коду:

> https://github.com/d-beekeeper/ratchat/blob/master/app/Server/RatchetServer.php#L112



закрытие соединения != выход юзера из комнаты

Также, здесь название функции неудачное:

https://github.com/d-beekeeper/ratchat/blob/master/app/Chat.php#L122

> public function leftUserFromRoom(User $user, $roomName)


> if ($this->roomHandler->removeUserFromRoom($user,$roomName)) {



Не очень понятно в чем разница между 2 функциями (а она должна быть, ведь они названы по-разному).

Позже я посмотрю код внимательнее.
#128 #433292
>>432555

А, еще, если будешь тестировать производительность то стоит поставить более хорошую библиотеку для ReactPHP. Скорее всего по умолчанию он использует StreamSelectLoop который не требует расширений. Но он основан на системном вызове ядра Select (получить список сокетов на которых доступны данные), производительность которого с ростом числа соединений стремится к нулю. Подробнее про проблему большого числа соединений:

http://www.kegel.com/c10k.html#top (англ, может быть сложно понять начинающему)

Так как select не может обеспечить нужной произвдительности, в ядро linux добавили оптимизированные методы (epoll по моему), и написали библиотеки libevent, libev, libuv, которые используют более быстрый метод и позволяют организовать event loop для обработки сокетов. Соответственно, установив расширение для PHP, ты сможешь использовать более производительсный способ работы с скоетами. Подключение, как я понимаю, не требует менять сам код, так как разница асбтрагируется внутри reactphp.

Потому для повышения производительности стоит поставить расширение вроде libev/libuv к PHP и использовать более быстрые сокеты. Список поддерживаемых драйверов тут: https://github.com/reactphp/react/wiki/Event-Loop-Implementations

libevent самая старая библиотека. libev более новая и тут http://libev.schmorp.de/bench.html пишут что она быстрее. Про libuv я ничего не знаю, кроме того что она используется как основа event loop в Node.JS.

Ну и еще, если делать тесты, было бы интересно попробовать запустить приложение под hiphop (JIT компилятор от фейсбука который может выполнять код быстрее — на долгоживущих процессах выгода должна быть).

> Кстати если подскажешь какую нибудь готовую oAuth библиотеку для Silex-Symphony (или вообще универсальную) для однообразной авторизации юзера через кучу разных соцсетей - буду очень благодарен.



Я ищу обычно библиотеки на phptrends. Вводи туда разные ключевые слова (oauth, symfony oauth, silex oauth) и посомтри что найдется. Я вижу например вот эта популярна:

https://github.com/thephpleague/oauth2-client

Если искать по symfony oauth то на первом месте вот это, но она по моему только под Symfony, то есть она хорошо интегрируется именно в большие проекты, а вот насчет Silex это вряд ли:

https://github.com/hwi/HWIOAuthBundle

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

По словам silex oauth там тоже что-то выпадает: https://github.com/gigablah/silex-oauth

Я кстати тут решил глянуть в твоем гитхабе (любопытно же), не делал ли ты что-то раньше из наших заданий и увидел там файлообменник. Интересно :3 Хотя не помню, видел ли я его раньше? Наверно, нет. Но если ты с файлообменника перешел на Symfony (ну или хотя бы Silex) и асинхронные сокеты, это прогресс.

Кстати, ты тестами позаниматься не хочешь? Тесты — вещь интересная, но их мало где пишут и не везде пишут правильно. А ведь они очень полезны и дают ощущение надежности кода, да и возможность в любой момент проверить все ли верно работе, тоже очень помогает. Ну и плюс это ступенька в твоем уровне знаний. Тесты для кода, тесты для веб-приложений. У меня есть урок-обзор (да, он пока плохонький, и примеров надо бы больше сделать, и может что-то объяснить, и задача там в конце неправильно придумана, надо ее переделать): https://gist.github.com/codedokode/a455bde7d0748c0a351a Но вот что-то пока никто до этого урока не дошел.

Не хочешь как-нибудь тестирование поизучать?
#128 #433292
>>432555

А, еще, если будешь тестировать производительность то стоит поставить более хорошую библиотеку для ReactPHP. Скорее всего по умолчанию он использует StreamSelectLoop который не требует расширений. Но он основан на системном вызове ядра Select (получить список сокетов на которых доступны данные), производительность которого с ростом числа соединений стремится к нулю. Подробнее про проблему большого числа соединений:

http://www.kegel.com/c10k.html#top (англ, может быть сложно понять начинающему)

Так как select не может обеспечить нужной произвдительности, в ядро linux добавили оптимизированные методы (epoll по моему), и написали библиотеки libevent, libev, libuv, которые используют более быстрый метод и позволяют организовать event loop для обработки сокетов. Соответственно, установив расширение для PHP, ты сможешь использовать более производительсный способ работы с скоетами. Подключение, как я понимаю, не требует менять сам код, так как разница асбтрагируется внутри reactphp.

Потому для повышения производительности стоит поставить расширение вроде libev/libuv к PHP и использовать более быстрые сокеты. Список поддерживаемых драйверов тут: https://github.com/reactphp/react/wiki/Event-Loop-Implementations

libevent самая старая библиотека. libev более новая и тут http://libev.schmorp.de/bench.html пишут что она быстрее. Про libuv я ничего не знаю, кроме того что она используется как основа event loop в Node.JS.

Ну и еще, если делать тесты, было бы интересно попробовать запустить приложение под hiphop (JIT компилятор от фейсбука который может выполнять код быстрее — на долгоживущих процессах выгода должна быть).

> Кстати если подскажешь какую нибудь готовую oAuth библиотеку для Silex-Symphony (или вообще универсальную) для однообразной авторизации юзера через кучу разных соцсетей - буду очень благодарен.



Я ищу обычно библиотеки на phptrends. Вводи туда разные ключевые слова (oauth, symfony oauth, silex oauth) и посомтри что найдется. Я вижу например вот эта популярна:

https://github.com/thephpleague/oauth2-client

Если искать по symfony oauth то на первом месте вот это, но она по моему только под Symfony, то есть она хорошо интегрируется именно в большие проекты, а вот насчет Silex это вряд ли:

https://github.com/hwi/HWIOAuthBundle

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

По словам silex oauth там тоже что-то выпадает: https://github.com/gigablah/silex-oauth

Я кстати тут решил глянуть в твоем гитхабе (любопытно же), не делал ли ты что-то раньше из наших заданий и увидел там файлообменник. Интересно :3 Хотя не помню, видел ли я его раньше? Наверно, нет. Но если ты с файлообменника перешел на Symfony (ну или хотя бы Silex) и асинхронные сокеты, это прогресс.

Кстати, ты тестами позаниматься не хочешь? Тесты — вещь интересная, но их мало где пишут и не везде пишут правильно. А ведь они очень полезны и дают ощущение надежности кода, да и возможность в любой момент проверить все ли верно работе, тоже очень помогает. Ну и плюс это ступенька в твоем уровне знаний. Тесты для кода, тесты для веб-приложений. У меня есть урок-обзор (да, он пока плохонький, и примеров надо бы больше сделать, и может что-то объяснить, и задача там в конце неправильно придумана, надо ее переделать): https://gist.github.com/codedokode/a455bde7d0748c0a351a Но вот что-то пока никто до этого урока не дошел.

Не хочешь как-нибудь тестирование поизучать?
#129 #433295
>>432568

> Выдает кучу ошибок


Ошибки надо исправить. У тебя ошибки из-за того что тут:

> $newPath = makeOneStep($paths, $stationName, $endPoint, $time, $lowerTime, $pathDone);


> if (!$lowerTime || ($newPath['time'] < $lowerTime)) {


Нет проверки на то, что makeOneStep нашла путь. Она ведь могла не найти путь и в этом случае возвращает пустой массив (кстати почему? нет логики. Лучше возвращать null).

То есть прежде чем обращаться к newPath['time'] надо проверить что в нем вообще что-то есть.

тут по-прежнему ошибка:

> $time += $paths[$startPoint][$stationName]['time'];



Допустим мы сейчас в A, и из нее можно проехать в B, C, D, E, F, ... Z. Цикл foreach начинает перебирать вершины B, C ... Z и на каждом шаге мы в time прибавляем время проезда от A до текущей вершины, то есть время пути AB, AC ...

В итоге в time к концу цикла будет старое значение time + AB + AC + AD + AE + AF ... + AZ. Что оно значит?

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

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

В строке 161-162 ради понятности напиши return array( ...);

Время (33) по моему у тебя выводится неправильное. Посчитай по карте сам.

То есть ты близок к решению, но надо исправить ошибки.
#129 #433295
>>432568

> Выдает кучу ошибок


Ошибки надо исправить. У тебя ошибки из-за того что тут:

> $newPath = makeOneStep($paths, $stationName, $endPoint, $time, $lowerTime, $pathDone);


> if (!$lowerTime || ($newPath['time'] < $lowerTime)) {


Нет проверки на то, что makeOneStep нашла путь. Она ведь могла не найти путь и в этом случае возвращает пустой массив (кстати почему? нет логики. Лучше возвращать null).

То есть прежде чем обращаться к newPath['time'] надо проверить что в нем вообще что-то есть.

тут по-прежнему ошибка:

> $time += $paths[$startPoint][$stationName]['time'];



Допустим мы сейчас в A, и из нее можно проехать в B, C, D, E, F, ... Z. Цикл foreach начинает перебирать вершины B, C ... Z и на каждом шаге мы в time прибавляем время проезда от A до текущей вершины, то есть время пути AB, AC ...

В итоге в time к концу цикла будет старое значение time + AB + AC + AD + AE + AF ... + AZ. Что оно значит?

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

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

В строке 161-162 ради понятности напиши return array( ...);

Время (33) по моему у тебя выводится неправильное. Посчитай по карте сам.

То есть ты близок к решению, но надо исправить ошибки.
#130 #433296
>>432984
>>433197

Ответил выше.

>>432604

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

А так, file:/// должно работать. В Хроме и FF работает.

Что значит у тебя не работает? Какая у тебя ОС? Что выводитяс при клике на ссылку?

>>432618

сделать форму и сохранять данные в базу.

>>432620

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

>>432623

Ты или кто-то другой ниже уже написал:

(что угодно){10} — регулярка в скобках должна совпасть с текстом 10 раз подряд
#130 #433296
>>432984
>>433197

Ответил выше.

>>432604

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

А так, file:/// должно работать. В Хроме и FF работает.

Что значит у тебя не работает? Какая у тебя ОС? Что выводитяс при клике на ссылку?

>>432618

сделать форму и сохранять данные в базу.

>>432620

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

>>432623

Ты или кто-то другой ниже уже написал:

(что угодно){10} — регулярка в скобках должна совпасть с текстом 10 раз подряд
#131 #433297
>>432649

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

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

>>432658

У jQUery есть метод noConflict для такого подключения, но это будет очень геморройно. может проще поменять библиотеку или исправить код?
#132 #433298
>>432653

> сам с собой на английском говорю.


> Иногда по скайпу общаюсь


Но хотя бы по скайпу не сам с собой?

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

>>432665

попробуй выписывать только название либо название + 2-3 слова поясняющую зачем она. А позже пересматривать листок и вспоминать. Но вообще, учить функции не требуется. Если ты постоянно пишешь код (в идеале часов по 8-10 в день) то ты все нужные функции запомнишь. А те, что не запомнишь, всегда можно посмотреть в мануале. Я не первый год на PHP пишу, но все равно периодиечски в мануал лезу. Главное знать, что для этого или того в php есть функция.

Также, IDE при вводе имени функции выдают подсказки по ней.

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

Ну и запоминать идеи и концепции проще, так как их меньше чем функций в PHP.
#133 #433304
>>432678

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

>>432708

Базу почисти и перезалей дамп. У меня та же ошибка была.

>>432728

Плюс складывает только числа по математическим правилам. Для склеивания (конкатенации не по-русски) строк используй точку: http://php.net/manual/ru/language.operators.string.php

>>432738

> каким тегом в макабе оформлять код?


Никаким. Сломали эту фичу.

>>432747

Ты используешь несуществующую переменную regxp (наверно имелось в виду check)

>>432771

То же самое.

>>432780

А как ты рельсы с метеором собрался объединять? метеор же JS использует на сервере.

Можно вкатиться, но я рельсы знаю очень плохо, так что больше буду HTML/JS проверять тогда. Ну и раз ты используешь такую сложную вещь как meteor.js, ты хорошо изучил его документацию? Знаешь, как он устроен и как работает?

Мне не нравится meteor, я тут полистал документацию (она плохая и невнятная, так как нормально не описывает ни концепции ни архитектуру), узнал что эти велосипедисты зачем-то сделали свой менеджер пакетов вместо npm, мне не нравится handlebars (у него ужасный и неудачный синтаксис), идея выполнять один код и там и там (во-первых, в этом не смысла, во-вторых, интуиция говорит что скоро код превратится в лапшу из Meteor.isServer/isClient со всеми вытекающими багами). Не нравится заточенность на MongoDB (у нее сових недостатков хватает).

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

Ну это так, мое мнение. Разобраться в нем в любом случае полезно.
#133 #433304
>>432678

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

>>432708

Базу почисти и перезалей дамп. У меня та же ошибка была.

>>432728

Плюс складывает только числа по математическим правилам. Для склеивания (конкатенации не по-русски) строк используй точку: http://php.net/manual/ru/language.operators.string.php

>>432738

> каким тегом в макабе оформлять код?


Никаким. Сломали эту фичу.

>>432747

Ты используешь несуществующую переменную regxp (наверно имелось в виду check)

>>432771

То же самое.

>>432780

А как ты рельсы с метеором собрался объединять? метеор же JS использует на сервере.

Можно вкатиться, но я рельсы знаю очень плохо, так что больше буду HTML/JS проверять тогда. Ну и раз ты используешь такую сложную вещь как meteor.js, ты хорошо изучил его документацию? Знаешь, как он устроен и как работает?

Мне не нравится meteor, я тут полистал документацию (она плохая и невнятная, так как нормально не описывает ни концепции ни архитектуру), узнал что эти велосипедисты зачем-то сделали свой менеджер пакетов вместо npm, мне не нравится handlebars (у него ужасный и неудачный синтаксис), идея выполнять один код и там и там (во-первых, в этом не смысла, во-вторых, интуиция говорит что скоро код превратится в лапшу из Meteor.isServer/isClient со всеми вытекающими багами). Не нравится заточенность на MongoDB (у нее сових недостатков хватает).

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

Ну это так, мое мнение. Разобраться в нем в любом случае полезно.
#134 #433306
>>432783

Ищи developer docs.

Wordpress: http://codex.wordpress.org/%D0%94%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%86%D0%B8%D1%8F_%D0%B4%D0%BB%D1%8F_%D1%80%D0%B0%D0%B7%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D1%87%D0%B8%D0%BA%D0%B0
Wordpress, англ: http://codex.wordpress.org/Developer_Documentation

Также, там есть «designer docs» то есть документация по созданию тем и натягиванию верстки (так как верстальщиков на западе почему-то назвают designer): http://codex.wordpress.org/Blog_Design_and_Layout

Drupal: https://www.drupal.org/documentation/develop
Drupal, создание тем: https://www.drupal.org/documentation/theme

Ну и так далее.

Если ты незнаком с конкретной CMS, стоит начать с установки и чтения руководства пользователя, а не разработчика, чтобы ты сначала научился админкой пользоваться.
#135 #433308
>>433000

Скобки не хватает открытой

>>433140

Вместо (\\-|\\(|\\)| ) гораздо удобнее и короче использовать [()\\-\\s]

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

> $chistka = '#((\\-|\\(|\\)| )*){10}#';


Тут непонятно зачем {10} приписана. Это выражение явно непраивльное, упрости его чтобы там было не больше 4-5 символов.

В общем да, работает, но надо доработать. ну и проверить что номера из неправильного списка все отсеиваются.
#136 #433309
Алсо, я тут в поисках доков к метеору наткнулся на статью http://habrahabr.ru/post/166885/ — комментарии забавные.

>>433189

Норм. Но имей в виду, что для поиска пути есть готовые алгоритмы (котооые лучше предоженного в задаче), например Дейкстра неплохой: https://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%BF%D1%83%D1%82%D0%B8
#137 #433328
ОП, три вопроса:
1) Почему все не рекомендуют ставить апач как службу под виндой и, упаси боже, делать его доступным из сети? Это правда так небезопасно? Как обезопаситься тогда?
2) зачем постоянно прописывать хосты в hosts, как прописывать их, если хочешь расшарить виртуальные хосты в сеть и как прописывать их на vps под никсами?
3) Решил заранее посмотреть вакансии и обалдел - джуниор, php, HTML/CSS, js(jquery), mvc, 2-4 фреймворка, опыт администрирования, еще что-нибудь, зарплата 40к. Это нормально, что даже сишнику с зарплатой вдвое выше надо знать вдвое меньше, чем джуниору php? Или достаточно поверхностных знаний уровня helloworld по тому же js?
#138 #433329
>>433308
http://ideone.com/ndiPgR
По неправильным прогнал, все отсеил.
#139 #433339
>>433328

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

> и, упаси боже, делать его доступным из сети?


Если ты делаешь его доступным снаружи, и ты не NAT (например не за роутером), по может быть соседи по локалке смогут зайти на твои локальные сайты, и например оставить там какие-нибудь нехорошие комментарии (если в примеру ты делаешь блог). Ну и если у тебя там какой-нибудь phpmyadmin и база без пароля, то они смогут залезть в нее.

> зачем постоянно прописывать хосты в hosts


Чтобы обращаться к локальному сайту по имени. Запись в hosts говорит ОС на твоем компьютере что имени X соотвутетвует Ip адрес Y.

> как прописывать их, если хочешь расшарить виртуальные хосты в сеть


Надо понимать что такое DNS и как она работает. DNS это система которая преобразует имя хоста вроде example.com в IP-адрес. Подробнее в вики: https://ru.wikipedia.org/wiki/DNS

Как видишь, DNS состоит из частей, которые под нашим контролем (файл hosts или свой DNS сервер) и которые не под нашим (чужой DNS сервер).

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

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

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

> как прописывать их на vps под никсами?


Ты прописываешь хосты не на сервере а на компьютере с которого смотришь сайт, чтобы он мог понять какому IP соответствует имя хоста. Если ты арендуешь VPS то скорее всего к нему бесплатно дают технический домен вроде server1234.example.com и ты можешь пользоваться им без настройки.
#139 #433339
>>433328

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

> и, упаси боже, делать его доступным из сети?


Если ты делаешь его доступным снаружи, и ты не NAT (например не за роутером), по может быть соседи по локалке смогут зайти на твои локальные сайты, и например оставить там какие-нибудь нехорошие комментарии (если в примеру ты делаешь блог). Ну и если у тебя там какой-нибудь phpmyadmin и база без пароля, то они смогут залезть в нее.

> зачем постоянно прописывать хосты в hosts


Чтобы обращаться к локальному сайту по имени. Запись в hosts говорит ОС на твоем компьютере что имени X соотвутетвует Ip адрес Y.

> как прописывать их, если хочешь расшарить виртуальные хосты в сеть


Надо понимать что такое DNS и как она работает. DNS это система которая преобразует имя хоста вроде example.com в IP-адрес. Подробнее в вики: https://ru.wikipedia.org/wiki/DNS

Как видишь, DNS состоит из частей, которые под нашим контролем (файл hosts или свой DNS сервер) и которые не под нашим (чужой DNS сервер).

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

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

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

> как прописывать их на vps под никсами?


Ты прописываешь хосты не на сервере а на компьютере с которого смотришь сайт, чтобы он мог понять какому IP соответствует имя хоста. Если ты арендуешь VPS то скорее всего к нему бесплатно дают технический домен вроде server1234.example.com и ты можешь пользоваться им без настройки.
#140 #433340
>>433328

> Это нормально, что даже сишнику с зарплатой вдвое выше надо знать вдвое меньше, чем джуниору php?


Это тебе кажется, что меньше. Я сомневаюсь, что со знаниями типичного PHP джуниора можно вообще что-то написать на Си. Ты же в одних указателях запутаешься. Да и на вакнсии «сишника» обычно требуется не только умение написать функцию сортировки массива, а Си++, шаблоны, std::, Boost, какую-нибудь GUI библиотеку и знание особенностей разных API.

> Или достаточно поверхностных знаний уровня helloworld по тому же js?


Зачастую да.
#141 #433343
>>433329

Хорошо. Тогда еще маленькое улучшение сделай. Подумай, как упростить выражение в $replace. Ну например, если сначала очистить номер, то replace можно будет записать значительно в более простой форме.
#142 #433345
>>433339
А у меня белый ип, в итоге поднятые у меня сайты доступны не только по локалке. Я не против тащемта.
#143 #433347
>>433345

Ну это твое дело, ок. Но вообще, сайты удобнее хостить на хостинге хотя бы потому что при перезагрузке/зависании/проблемах с электричеством/забыл за инет заплатить/взял ноут с собой они не отключатся.
#144 #433348
>>433347

А хотя если речь идет о локальных сайтах для разработки то конечно проблем никаких нет.
#145 #433349
>>433348
Ага, мне просто не жалко, если какая-то хрень забредет.
#146 #433350
>>433198

Спасибо.

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


Ну я сейчас заканчиваю учебник ОПа, да. Вроде неплохо справляюсь, пока что.
Калькулятор делал, Денвер поставил себе.

>но лучше переучить чем недоучить


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

>>433199

Ну я не в ДСах, но околомиллионник.
А что могут спрашивать на собеседовании?
Что в резюме писать?
#147 #433406
>>433279

> Сразу скажу, у меня есть ощущение что при залогинивании из нескольких браузеров/устройств одним пользователем там могут быть какие-то баги. Ты проверял это? закрытие соединения != выход юзера из комнаты



Интуиция тебя не обманула :) Да, если из нескольких браузеров один и тот же юзер зайдет в комнату, а потом в одном из браузеров выйдет из комнаты - то он пропадет из списка юзеров этой комнаты. Хотя из других браузеров он всё ещё сможет посылать в них сообщения.
Очевидно надо как то запоминать соответствие "отдельный юзер -> массив его подключений -> массив комнат каждого подключения". И рассылать извещение о выходе из комнаты только тогда, когда нет больше ни одного подключения с этой комнатой.

>Не очень понятно в чем разница между 2 функциями


В том что removeUserFromRoom только удаляет юзера из комнаты в БД, а leftUserFromRoom ещё и генерирует эвент чата, типа "выход юзера из комнаты".

>>433292

>А, еще, если будешь тестировать производительность то стоит поставить более хорошую библиотеку для ReactPHP. Скорее всего по умолчанию он использует StreamSelectLoop... libevent самая старая библиотека....


Да, все это есть в доках к Ratchet. Я на свой тестовый сервер libevent не ставил, но, судя по докам Ratchet, достаточно просто её поставить, и она начнет автоматически использоваться. Ничего в коде менять не надо.

>Я ищу обычно библиотеки на phptrends


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

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



Ты его проверял, это было почти год назад, не трать время.
#148 #433408
>>433292

>Кстати, ты тестами позаниматься не хочешь? Тесты — вещь интересная



Да, обязательно, только чуть позже. Щас я осиливаю
http://symfony.in.ua/creating-blog-symfony2-symblog-tutorial.html
Как закончу - потом в планах книжка
Мэтт Зандстра — PHP: Объекты, шаблоны, методики программирования
А потом тестами займусь
#149 #433415
>>433279

> Ты не делал никаких нагрузочных тестов?


Нет, не делал. Но очевидно, что будет проблема, если к чату будет подключено много AJAX клиентов. Ибо каждый такой клиент - это 1 запрос в секунду. 50 клиентов - 50 запросов\сек.
Там надо серьёзно поработать над кешированием, чтоб БД не сдохла под навалом запросов.
#150 #433439
>>432438
ОП, ну посоветуй что-то, пожалуйста
#154 #433485
Расскажите, а где пхп будет искать файл если я напишу file_get_contents('file.txt')? Только в директории где был вызван скрипт?
#155 #433494
Друзья, есть вопрос. Наверняка он уже много раз проскальзывал в том или ином виде, но всё же.

Кто внятно и структурировано может объяснить, что должен знать и уметь php-программист на позициях:
-junior
-middle
-senior

Проблема в том, что скоро планирую устраиваться куда-нибудь в офис. До этого фрилансил. Соответственно объективно себя оценить не могу. И не знаю на какую позицию отправлять резюме.
sage #156 #433524
>>433494
если ты только начинаешь, ещи senior позиции
junior это роли для матёрых девелоперов
middle - менеджеры/hr
#157 #433586
>>433524
И стоило тратить время чтобы такую хуйню сказать? Юмор уровня /b.
#158 #433590
>>433524

>сажамен сново помог беднаму вопрашающиму)))))

#159 #433593
>>433494
Гугли "php book собеседование"
#160 #433632
>>433474
strtr очень умная функция, ищет сначала длинные кусочки как я понял, а потом уже короткие
могла бы мой "тест" побуквенно заменить, но нет, заменила целиком.
http://ideone.com/rljkHI
#161 #433635
>>433593
Видел я эту книгу давно. Там простые вопросы очень. Это какой уровень? Junior?
33 Кб, 3200x460
Клиент-серверное приложение на PHP+JS+AJAX #162 #433641
Дублирую:
Сап, программач.

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

Т.к. никогда ранее подобное не писал, решил спросить здесь, насчёт адекватности архитектуры, элементы которой таковы:
- тонкий сервер (php) и толстый клиент (js);
- не использовать сессии, ограничившись куками (через js), в которых хранить имя юзера и хэш пароля;
- при каждом действии юзера, подразумевающем обращение к серверу, генерировать ajax запрос, куда включать и данные юзера из кук для проверки прав доступа;
- все действия на сервере делать, используя PDО, чтобы исключить риск SQL-инъекций;

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

Спасибо.
#163 #433645
>>433635
Там же написано
#164 #433658
>>433641
Толстый клиент - это скорей десктоп приложение, а в твоем случае необходимо реализовать одностраничное приложение (SPA, или как его называли раньше Rich Internet Application). Хранить ассоциированную с пользователем информацию лучше на стороне сервера, а пользователю отдавать идентификатор сессии в виде куки. Этот паттерн описан у Фаулера под названием "хранение информации на стороне сервера и на стороне клиента". Далее тебе необходим слой персистирования данных - лучше всего заюзать какую нибудь легковесную ORM. Соответственно, тебе потребуется составить модель данных предметной области - выделить основные сущности, взаимосвязи между ними, их атрибуты. Эту работу лучше всего произвести в первую очередь. Не забудь о нормализации этой модели в случае использования реляционного источника данных. Затем тебе необходимо спроектировать структуру объектов, которые будут передаваться от сервера к клиенту и обратно. Такие объекты принято называть DTO, очень рекомендую прочитать описание этого паттерна все у того же Фаулера. Серверный код может формировать json с этими объектами по запросу пользователя.
#165 #433660
>>433658
Если каждый объект предсетной области досткпен по уникальному адресу, а действия над объектом выполняются при помощи GET/POST/PUT/DELETE методов - речь идет о RESTFul API. Существует масса решений для организации такого подхода, рекомендую взять готовый код и связать его с твоей ORM.
#166 #433661
>>433658
1) Т.е. при корректном логине, присваивать новый сгенерированный идентификатор, записывать его в БД и проверять уже соответствие ему при каждом действии до тех пор, пока юзер не сделал логаут?
2) ORM простенькую планировал сам накидать, но если таки использовать, какую посоветуешь?
3) Тоже планировал использовать JSON для получения данных, но не будет ли проблем при больших массивах данных?
Фаулера почитаю, спасибо за ответ.
#167 #433663
>>433658

>у Фаулера


Cсылку, будьте любезны.
#168 #433686
Почему, когда я захожу в тред своего любимого языка С++, я вижу лишь ненависть, рвоту и сагающих страперов? Почему, зайдя в тред неугодного мне языка, я увидел любовь, понимание и обожание?
#169 #433687
>>433686
Потому что вы байтоёбы, вот и беситесь.
#170 #433689
>>433686
Не знаю, может быть потому что там чсвшные личности сидят по большей части? Ну а мы тут копошимся в своем мирке не претендуя ни на что.
#171 #433691
>>433689
Наоборот же крестопетух ни на что не претендует, кроме чсв в своем же манямирке. Местные - вечные студентики с лаба1.срр. О том, что там в реальной жизни крутого делается на любимых крестах они только рассуждать могут, сами не принимая в этом участия, вот и бесятся.
#172 #433693
>>433691

>Местные - вечные студентики с лаба1.срр.


И как можно "любить" язык, когда у тебя лаба1.cpp? Ты же ничего о нем не знаешь.
мимо-лаба8.cpp
#173 #433694
>>433693
Утята, вот и любят.
#175 #433747
>>433632

Да, сначала длинные, а потом короткие, это специально (иначе длинные не заменятся).

>>433641

> толстый клиент (js);


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

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

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

> генерировать ajax запрос, куда включать и данные юзера из кук для проверки прав доступа;


Они и так по умолчанию передаются вместе аякс запросом.

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


Не обобряют бессмысленное прикручивание аякса но раз так требует задание...
#176 #433749
>>433658

> Хранить ассоциированную с пользователем информацию лучше на стороне сервера, а пользователю отдавать идентификатор сессии в виде куки.


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

Не говоря о том что сессии и REST вообще плохо стыкуются (потмоу что stateless transfer).

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


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

> Такие объекты принято называть DTO


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

В общем, ты написал какую-то ерунду. Лучше бы написал как сдеать чтобы модели и там и там не дублировать (мое решение — не испольщовать модели на клиенте а использовать аякс).
#177 #433751
>>433660

REST API хорощо подходит для написания АПИ, но плохо подходит для приложений. Почему — предлагаю экспертам по новомодным хипстатехнллогиям догадаться самостоятельно.

>>433661

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


Это лишнее усложнение которое ничего не дает

> ORM простенькую планировал сам накидать, но если таки использовать, какую посоветуешь?


Либо готовую либо на SQL запросах делать, как быстрее выйдет

> Тоже планировал использовать JSON для получения данных, но не будет ли проблем при больших массивах данных?


Твое дело, но по моему проще передавать с сервера готовый HTML. Формально требования задачи соблюдены. У тебя задача сделать проще и быстрее или усложнить себе жизнь?
#178 #433754
>>433295
Ошибки убрал, но вот с time не придумал ещё как пофиксить

>В итоге в time к концу цикла будет старое значение time + AB + AC + AD + AE + AF ... + AZ.


Не знаю куда впихнуть тогда счетчик чтобы не плюсовал всё подряд, есть подсказки?

Я уже попробовал переделать функцию чтобы она все результаты вывела в массив и уже результаты отсеять по времени, но массив семимерный выходит и с ним потом сложно будет работать.
#179 #433756
>>433754

> Не знаю куда впихнуть тогда счетчик чтобы не плюсовал всё подряд, есть подсказки?



Сделать копию переменной
Прибавлять время к этой копии, не трогая саму исходную переменную.
#180 #433758
Ребятки. Нужны деньги, - решил освоить PHP/HTML/JS - веб-дерьмо. Собственно, хтмл вроде бы на начальном уровне усвоил (можно сверстать какой-нибудь макет или парочку, для укрепления результата), вопрос, в одеск-треде пишут что начальный рейт для ньюфага - 10 баксов. Что для этого нужно уметь в PHP?
4 Кб, 87x65
#181 #433759
>>433751
>>433747
1) В ТЗ явно не фигурирует JSON и AJAX, это моя идея, т.к. я раньше с ними работал, под них есть готовые наброски кода.
2) Первое время у проекта не будет мощного сервера, поэтому я и стараюсь максимально разгрузить серверный код, ограничившись работой с БД, и, чтобы минимизировать как нагрузку, так и объём данных, переводить их в JSON и отправлять клиенту.
3) >Это лишнее усложнение которое ничего не дает
Но это же лучше, чем хранить хэш пароля в куках?
#182 #433765
>>431924
Сап пхпач.
Я начал проходить ваш первый учебник и столкнулся с первой своей проблемой.
http://ideone.com/dycYT5
Расскажите как записать дешифровку шифровки чегото я сам не догоняю.
#183 #433768
>>433759

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


На сколько ты разгрузишь серверный код? С чего ты взял что рендеринг на клиенте ускорит работу сервера? Ты хотя бы оценку (не говоря про тесты) делал? Ты ради воображаемой оптимизации меняешь архитектуру. Так ты далеко не уйдешь.
#184 #433770
Что-то не пойму: вот я пытаюсь генерировать токен для куки при каждом заходе на страницу и записывать его в скрытую форму, но при сабмите формы токен меняется (при сабмите страница обновляется?), в итоге в форме записано предыдущее значение кук и проверка на равенство не проходится.
#185 #433773
>>433759

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

Насчет сервера, скорее всего ты ничего не выиграешь от передачи данных в JSON. Наоборот. при кривой реализации все будет работать медленее и требовать больше запросов, не знаю как сервер, а со стороны пользователя будет грузиться дольше.
#186 #433774
>>433770

Не генерируй новый токен. Это неправильно так как если открыть страницу во второй вкладке то сгенерируется новый токен, а токен с первой страниц устареет.
#187 #433776
>>433765

Ты $ перед str забыл
#188 #433777
>>433765

Также, прочти мануал по array_flip
#189 #433779
>>433774
Как же его генерировать?
#190 #433782
>>433768
Архитектуры как раз пока и нет, пока я планирую и ищу наиболее оптимальный вариант.
>>433773
Дневник - иллюстрация структуры приложения. Пользоваться им будут 10-15 человек одновременно (смешно, да?), но запросы и изменения будут вноситься раз в минуту где-то, объём объектов в БД - несколько сотен.

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


Собственно, на сервере ответ, после получения массива из БД, например, будет посылаться возвращаться через аякс как echo json_encode($arr) куда уж проще сделать?
#191 #433789
>>433779

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

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

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

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

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

Также, ты можешь очистить куки, открыть отладчик (Ctrl + Shift + I) и изучить как сделаны токены на других сайтах, например, вконтакте (у них токен в страницу вписан и его легко найти), фейсбук (хотя у них там скриптов много накручено, трудно наверно понять), и аналогчиные.
#192 #433795
>>433756
И передавать её внутрь рекурсивной функции? Не совсем понял как реализовать то
#193 #433797
>>433795

Сейчас у тебя сделано так (если упростить код):

// сколько потрачено времени чтобы добраться до текущей точки
$time = 10;
// допустим это время пути из текущей точик в ссоедние
$points = array('b' => 1, 'c' => 2, 'd' => 3);

foreach ($points as $name => $pointTime) {
$time += $pointTime;
echo "t=$time чтобы добраться до $name\n";
}

То есть все время складывается в одну перемнную и выводится t = 11, t = 13, t = 16. Исправь, чтобы не складывалось и программа писала:

t = 11 до точки b
t = 12 до точки c
t = 13 до точки d
#194 #433804
>>433777
Прочитал мануал, так и не понял. Что у меня должно быть в скобках под array_flip. По ходу дела $code. Но тогда В расшифровке просто пишет Array.
http://ideone.com/VlcSYz
#195 #433818
>>433797
Эт я знаю, я только не понял как мне через временную переменную решить проблему
#196 #433858
>>433818

Ну ты код который я написал, можешь переделать чтобы он выводил 11, 12, 13 а не то что сейчас? Любым способом, который знаешь. Или нужна подсказка? Или сам знаешь как сделать?
#197 #433859
>>433804

Посомтри внимательно внизу на ideone:

> PHP Warning: array_flip() expects parameter 1 to be array, string given


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

[ x => 1, y => 'hello'] а она вернет [ 1 => 'x', 'hello' => 'y' ]

чтобы увидеть содержимое массива ($ras) используй var_dump($ras), echo не умеет выводить массивы.
#198 #433888
https://github.com/MindiMakridi/Students Вроде исправил, по крайней мере тот xsrf Файл больше не может редактировать мой профиль.
#199 #433894
>>433888

Ты сделал, но очень неуниверсально. Смотри, ты прямо вписал проверки в код profile.php. Но было бы гораздо лучше вынести это в функцию с соотв. названием:

createXsrfCookie() — создает с нуля или продлевает XSRF-куку, и возвращает значение токена

Для проверки можно тоже сделать функцию, можно не делать.

Вместо «произошла ошибка» надо просить отправить форму еще раз.
#201 #433936
>>433858
Спасибо, я первый раз видимо жопой прочитал вот этот пост >>433797
>>433295

http://ideone.com/aq9trR
https://github.com/Si0n/phpandsoon
Вот, допилил финальную версию, надеюсь всё хорошо.
#202 #433949
>>433936

Код требует улучшений, конечно.

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

Ну или объясни зачем она нужна и почему без нее работать не будет.

Далее,

> $time = 0, $lowerTime = 5000, $pathDone)


Незачем тут давать значения по умолчанию, так как они не исопльзуются

Вместо 5000 можно использовать константу INF которая обозначает бесконечность (да, в компьютерной математике предусмотрена бесконечность): http://php.net/manual/ru/math.constants.php

Для проверки на бесконечность нельзя использовать == (то есть 2 бесконечночти не равны между собой, что логично) но есть функция: http://php.net/manual/ru/function.is-infinite.php

Далее, вот тут

> $result['path'] = $pathDone;


> $result['time'] = $time;



лучше написать return array('path' => ..., 'time' => ..) чтобы было более очевидно.

Далее, при остутсвии оптимального пути надо возвращать не пустой массив, а null.

Далее, непонятно зачем тут писать 2 строки

> $result = $shortest;


> return $result;



если можно записать сразу return.

далее, тут у тебя огромный иф:

> if (!in_array($stationName, $pathDone)) {



Надо его перевернуть таким образом:

Если (станция уже есть в пути) {
пропустить этот вариант;
}
#202 #433949
>>433936

Код требует улучшений, конечно.

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

Ну или объясни зачем она нужна и почему без нее работать не будет.

Далее,

> $time = 0, $lowerTime = 5000, $pathDone)


Незачем тут давать значения по умолчанию, так как они не исопльзуются

Вместо 5000 можно использовать константу INF которая обозначает бесконечность (да, в компьютерной математике предусмотрена бесконечность): http://php.net/manual/ru/math.constants.php

Для проверки на бесконечность нельзя использовать == (то есть 2 бесконечночти не равны между собой, что логично) но есть функция: http://php.net/manual/ru/function.is-infinite.php

Далее, вот тут

> $result['path'] = $pathDone;


> $result['time'] = $time;



лучше написать return array('path' => ..., 'time' => ..) чтобы было более очевидно.

Далее, при остутсвии оптимального пути надо возвращать не пустой массив, а null.

Далее, непонятно зачем тут писать 2 строки

> $result = $shortest;


> return $result;



если можно записать сразу return.

далее, тут у тебя огромный иф:

> if (!in_array($stationName, $pathDone)) {



Надо его перевернуть таким образом:

Если (станция уже есть в пути) {
пропустить этот вариант;
}
#203 #433953
>>433936

> https://github.com/Si0n/phpandsoon/blob/master/Navigate2.php#L198


> for ($i = 0; $i < count($path['path']); $i++) {


Для перебора массива удобнее (и код читается проще) использовать foreach

далее, эти 2 строчки:

> https://github.com/Si0n/phpandsoon/blob/master/Navigate2.php#L170


> $xTime = $time;


> $xTime += $pointTime;



Можно заменить на одну.
#204 #433955
>>433908

Если кука существует, надо продлить ей жизнь на 3 часа. а то у тебя она умирает через 3 часа после первой установки и может умереть в процессе взаимодействия пользователя с сайтом.
#206 #433963
>>433959

А ты проверял код?

> setcookie("studentscookie[token]", generateToken(), time()+60603, "/");


> return $_COOKIE['studentscookie']['token'];



setcookie по моему не заполняет массив COOKIE, это лишь массив пришедших от пользователя кук.

Чтобы не было повторов, надо time()+60603 вынести в переменную.
#207 #433965
>>433963
Проверял, ошибок не заметил.
#208 #433974
>>433965

Если зайти незарегистрированным и без кук то на странице /profile.php выводится ошибка:

> Notice: Undefined variable: token in D:\mm\templates\profile.html on line 25



Выводится ли она у тебя? Если нет, то у тебя может быть отключено отображение ошибок. Надо включить display_errors = On либо смотреть ошибку в логах.
#209 #433976
>>433965

Раз уж ты защитил редактирование токеном, защити еще и регистрацию и выход с сайта, хорошо?
#210 #433983
>>433965

Ну и ошибка все же есть. Если зарегистрироватьяс, в отладчике удалить куку token (в Хроме куки удаляются в отладчике на вкладке resources) то при заходе на profile.php пишет:

> Notice: Undefined index: token in D:\mm\lib\functions.php on line 59



То есть setcookie не заполняет массив _COOKIE и код все же не совсем верный.
#211 #433986
https://github.com/MindiMakridi/Students
Теперь ошибок быть не должно, по крайней мере в логе я ничего не увидел.
#212 #433988
Анончики, а где можно почитать про настройку апача в линуксе, ну или есть какая-нить годная книжка по этому делу (можно с пхп)?
#213 #433989
>>433986

Баг описанный тут >>433983\t остался
#214 #433993
>>433988

В Апаче там только конфиг можно менять. Онобычно раскидан по файлам в /etc/apache2/

Почитать можно доки Апача про формат конфига: http://httpd.apache.org/docs/2.4/configuring.html

У Апача есть базовые директивы, а есть директивы настройки модулей, она доступны только если подключен тот или иной модуль. Базовые: http://httpd.apache.org/docs/2.4/mod/core.html

Остальные, по модулям: http://httpd.apache.org/docs/2.4/mod/

Про особенности того, как разложены файлы конфига надо читать документацию дистрибутива. Вот для дебиана например: http://debian-handbook.info/browse/stable/sect.http-web-server.html (нангуглено по debian apache config)

Если у тебя есть более конкретный вопрос, «как настроить чтобы при X появлялось Y» то гугли или спрашивай тут.
#215 #433994
>>433989
Действительно. Хотя если обновить ошибка пропадает. Честно говоря я в тупике. Не понимаю почему так происходит. Должно же ставится куки, если его не существует, и ставится ведь, но только если обновить страницу.
#216 #433996
>>433994
Еще, кстати, заметил, что при выходе куки с токеном не удаляются, хотя должны. Удаляются, только если нажать выход два раза. Очень странно.
#217 #433997
>>433994

Функция setcookie не меняет массив _COOKIE. Этот массив содержит только пришедшие из браузера до выполнения скрипта куки и не обновляется в дальнейшем. Попробуй проверить сам, поставив var_dump(COOKIE) до и после setcookie.
13 Кб, 867x419
#218 #434003
>>433997
Итак единственное решение, пришедшее мне в голову, это переадресация в блоке else, но после того, как я добавил после Setcookie строчку header("Location: $currentPage"); мне выдает пикрелейтед
#219 #434006
>>434003

Решение неверное. Зачем делать редирект? Тебе вообще не нужен COOKIE в этом случае. Просто верни через return только что сгенерированный код.
#221 #434027
Я тут случайно открыл главную /pr и что-то было не так. Я сразу догадпася, что над ней поработали нододети (хотел написать нододебилы, но потом подумал что все же у людей наверно были хорошие намерения и не стоит про них так говорить). Как, спросите вы? Очень просто — они сделали так, что теперь там только одна страница, докрутить до подвала страницу невозможно, открыть N-ю страницу быстро невозможно, линейка прокрутки прыгает, в общем ад какой-то.

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

Это мне почему-то напомнало случай, когда заказчик при разработке сайта просил добавить в угол часы. Да, это не выдумка, они действительно так просят сделать.
#222 #434048
>>433711
Мне нужна оценка на эту задачу! Я понимаю что все работает, но у меня есть подозрение, что можно было её через цикл решить или типа того. Я упустил какой-то хороший прием тут?
#223 #434056
>>434048

Что-то я пропустил эту задачу.

Все решено верно. Вместо mt_rand(0, count($words2)-1) можно использовать array_rand, но разницы особой, что именно использовать, нету.

Ну и стихи получились забавные.

Решай задачки дальше, там скоро регулярки будут, они чуть посложнее.
37 Кб, 268x201
#224 #434059
Господа, про какую именно книгу тут цитата была?

>Фаулера под названием "хранение информации на стороне сервера и на стороне клиента"

#225 #434075
>>434059

Про воображаемую видимо.
#226 #434181
Антоша подскажи куда копать по заданию на JS #4

"Возвращаемая функция должна принимать любое количество аргументов и передавать их функции fn"

Я могу явно задать аргументы и передать их функции, но тогда их будет не любое количество.
Знаю, что есть arguments, но дальше ничего сделать с этим не могу. Нагуглил про "функции с переменным числом аргументов", но кажется, что это не то.
#227 #434183
>>434181

http://learn.javascript.ru/this#метод-apply
http://javascript.ru/Function/apply

Принимает массив с любым числом аргументов
#228 #434190
>>433350

> А что могут спрашивать на собеседовании?


Разное. Кратко вопросы можно разделить на типы:

- теория: что такое транзакция в БД? Что такое внешние ключи? что такое цикл?
- подвохи: что выведет код var_dump("x" == 0) ? Что выведет код if (array()) { echo "yes"; } ? Что выведет код $x = 'a'; $x++; echo $x; ? Какими функциями php можно выставить куку? Чтобы не бояться подвохов, стоит перечитать мануал.
- нормальные вопросы: как сделать X в языке Y?
- написать код/решить задачу
- ненормальные вопросы: кем вы видите себя через 5 лет? Почему мы должны взять именно вас? Почему люки круглые? почему у вас в X лет до сих пор нет опыта работы?
#229 #434192
>>433439

Залей код куда-нибудь на jsfiddle или codepen. Алсо, ты гуглил «центрирование по вертикали в CSS»? Это отдельная сложная тема.

Если высота блока известна можно просто сделать top 50%; margin-top: -200px; где 200px это половина высоты.
#230 #434193
>>433444

Ок, теперь все верно.

>>433462

Прочитал как «будет ли у меня сегодня свет» и пожалел автора.

>>433474

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

>>433485

Есть такое понятие как «текущая директория». Ее можно увидеть функцией http://php.net/manual/ru/function.getcwd.php и поменять функцией http://php.net/manual/ru/function.chdir.php

Если ты не указываешь абсолютный путь к файлу (начинающийся со слеша или диска, например c:/hello или /hello.txt) то файл ищется в текущей директории.

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

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

> Только в директории где был вызван скрипт

#231 #434194
>>433494

http://dou.ua/lenta/columns/junior-middle-senior-kakimi-popugayami-meryaem/
https://toster.ru/q/124171
http://www.gamedev.ru/industry/forum/?id=143383
http://anton.shevchuk.name/project-management/developers-rank/
http://dev.by/lenta/main/junior-vs-intermediate-vs-senior

Разница в опыте, знании технологий уровне ответственности и самостоятельности.

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

Если у тебя 0 опыта, ты можешь претендовать только на должноть джуниор или стажер.
#232 #434195
>>433632

Эта задача тоже решена верно.

>>433686

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

ну или переходи на сторону php, у нас есть печеньки! на самом деле нет
#233 #434196
>>433758

Наверно лучше спросить в одеск-треде у тех, кто получает эти 10 баксов? Скорее всего, как минимум нужно знать сам язык и какой-нибудь фреймворк.
#234 #434200
Привет Анон, делаю борду на php по этой пасте http://pastebin.com/UwxtZh9i. Возник такой вопрос - как сделать так чтобы к каждому треду показывались 3 последних поста (прям как на дваче)?
#235 #434203
>>433993
Делал по этому мануалу http://www.if-not-true-then-false.com/2010/install-mysql-on-fedora-centos-red-hat-rhel/
комп подключен к роутеру, подключенный к роутеру ноут по идее должен видеть локалхост компа? Подключаюсь по ипу компа.
#236 #434206
>>434011
Теперь всё верно, ОП?
#237 #434211
Пацаны, дам вам совет, как только более-менее уверенно начнете писать на пхп, бросайте его и учите какой-нибудь адекватный язык (Java, C# - беспроигрышные варианты, но можно и кресты, и питон, руби, да хоть что). И денег больше, и интереснее, и сами языки куда лучше полуооп-параши пхп.
Сам начинал с пхп, и очень рад, что не стал в итоге макакой.
#238 #434214
>>434206
Мельком посмотрел, у тебя здесь ошибка наверное:

> trim($_GET['search'] != "")


Надо: trim($_GET['search']) != ""
не ОП
#239 #434219
>>434211
Пусть учат, почему нет? Говнокодить можно везде, как и писать нормальный код
#240 #434226
Появилась задача переписать сайтик на PHP за выходные. Никогда с этим языком не работал. До этого писал только на Java и фронтэнд на js. Немного помню C++. Что мне лучше почитать, чтобы быстро освоиться в PHP? Особенно интересуют вопросы модели памяти, многопоточности, жизненного цикла приложения (инициализация, обработка HTTP-запросов, завершение работы) и, немного, как там устроена сборка мусора.
#241 #434249
>>434226

>сборка мусора


Референс каунтер c алгоритмом поиска циклических ссылок.
http://php.net/manual/ru/features.gc.php

>модель памяти


http://www.phpinternalsbook.com/zvals/memory_management.html
zval контейнры, copy-on-write и т.д. По управлению памятью ничего особо нет, на запуске скрипта резервируется кусман памяти указанный в php.ini, при выходе за его пределы - рантайм иксепшн. Вот ещё норм статья:
http://habrahabr.ru/post/134784/ там под ней тоже много хороших ссылок.

>жизненного цикла приложения (инициализация, обработка HTTP-запросов, завершение работы)


Пхп стоит за апачем как правило, хотя можно поднять php-fpm и поставить за nginx, но это уже сорт оф танцы с бубном. Т.е. http запрос идёт на вебсервер (в 90% случаев апаче), тот запускает php интерпретатор на каждый реквест в своём треде и запихивает ему в инпат распарсенные данные из запроса, в пыхе к ним уже можно обращаться через всякие $_REQUEST, $_POST, $_GET и т.д, хотя как правило фреймворки оборачивают это всё ещё одним слоем абстракции. Дальше пхп выполняет работу, выплёвывает в аутпут данные которые летят клиенту в качестве ответа (апач заголовки ответа генерит сам, хотя с пыхи можно в это дело вмешаться) и умирает. С использованием php-fpm можно сделать так, чтобы инстансы пхп не запускались на каждый реквест, а висели и ждали запросов, но это посложнее.

>многопоточности


Не стоит вскрывать эту тему. Обёрка pthreads есть, но весьма нирекамендую, там половина не работает. Многозадачность в пыхе обычно строится (на самом деле почти никогда этим никто не занимается) на процессовом взаимодействии со всякими лоу левел обёртками над posix или cntl типа proc_open, pcntl_fork и работу через пайпы, stream_select, posix_kill, а то и вообще голых вызовах exec/passthru/system но тоже не рекомендую, по понятным причинам.
#242 #434285
У меня от $_POST ошибка 403 в xampp'е. Че делать?
#243 #434352
Если кому ещё надо, книжка - Фаулер - Архитектура корпоративных программных приложений

>>434059 -кун
#244 #434374
Некоторое время назад приходил сюда за полезными для опыта заданиями, ОП посоветовал заняться https://gist.github.com/codedokode/d7e7f11449fc3bcb24b4 , сейчас у меня образовался кусок времени и я начал ее разгребать.
Так вот, там указано

>>Надо использовать ООП


С ООП я знаком, но как именно присобачить его сюда на практике? И где прочитать про то, для чего как и где следует использовать ООП?
#245 #434375
>>434374
Выдели сущности, запили по ним классы.
https://gist.github.com/codedokode/c4cbc4d7dc8e45ea074a
Посмотри.
#246 #434404
>>433153
https://github.com/tokotun/matriculant
Ну, надеюсь верно я подправил.

Теперь пытаюсь с Твигом разобраться
Выводит ошибку Fatal error: Uncaught exception 'Twig_Error_Loader' with message 'The "/templates" directory does not exist.
Не может найти шаблон ни как не пойму почему.
https://github.com/tokotun/twig

Если буду постигать PHP каждый день по часику, глядишь лет через 15 стану джуниором
#247 #434408
Access forbidden!

You don't have permission to access the requested object. It is either read-protected or not readable by the server.

If you think this is a server error, please contact the webmaster.
Error 403
localhost
Apache/2.4.10 (Win32) OpenSSL/1.0.1h PHP/5.4.31

В чём дело?
#248 #434410
Оп, я попробовал тут набросать действий в контроллере по попыткам. Есть мысль еще перенести их все в новый контроллер, чтобы в текущем было только то, что касается тестов. Ну и еще я сильно сомневаюсь в том, что я там наделал с куками.
https://github.com/sqghub/TestHub
#249 #434418
>>434211
Распиши лучше подробно весь свой путь, начиная с первых шагов и до сегодняшнего дня, пришел ли к успеху?
#250 #434419
>>434418

>пришел ли к успеху?


Он занимается тем, что сидит на дваче и срет в пхп треде. Как ты думаешь, он пришел к успеху?
#251 #434424
http://ideone.com/MT1k1O

Решил на палиндром задачку.
54 Кб, 911x867
#252 #434428
Запостил.

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

Спасибо той няше, что сделала http://archive-ipq-co.narod.ru/
#253 #434440
>>434428
зачем exit() пишешь когда он не нужен?
#254 #434458
Чому не работает?
http://ideone.com/ZmxWeZ
#255 #434468
>>434440
На пикрелейтед было в аналогичной ситуации. Вот и пишу.

>после прохождения этого мини-учебника какую литературу почитать?


Бамп вопросу.
71 Кб, 1000x764
#256 #434472
Забыл пикчу.
>>434468
#257 #434477
>>434249
Спасибо за ответы. Правда я сейчас задумался, может всё-таки на Питоне попробовать переписать.
#258 #434481
http://ideone.com/YvJYE1

Почему не выводится результат?
#259 #434483
>>434481
Может потому, что у тебя условий на 9 чисел, а число может быть любым, от 0 до 99999?
http://ideone.com/u058sY
#260 #434486
Какого черта то что я делаю в foreach не сохраняется в оригинальном массиве?
http://ideone.com/x9dG1R
#261 #434487
>>434483
http://ideone.com/ug2yag
Сделал. Возможно ли это было сделать как-то по-иному, чтобы сократить код?
#262 #434488
>>434487
А в чем суть программы вообще? Зачем вычислять остаток от деления? Что-то я не помню ничего такого в задачах опа.
#263 #434489
>>434486
В foreach после as идут временные переменные, любые действия с ними никак не влияют на оригинальный массив.
#264 #434490
+ >>434487
Не понимат. Гляди:
if ($roulette >= 99) // это если $рулетте БОЛЬШЕ ИЛИ РАВНО 99-ти (что странно, так работает), хотя по логике должно быть МЕНЬШЕ ИЛИ РАВНО (а так не работает, я проверял).
ЧЗХ?
#265 #434491
>>434488
http://archive-ipq-co.narod.ru/l1/conditions.html

См. "W4.2" (в конце статьи)
#266 #434493
>>434491
Но там же написано, что чтобы найти последнюю цифру, нужен остаток от деления числа на 10. А у тебя и на 1000 делится и на 100, не понятно зачем.
#267 #434494
>>434489
PeaceDOS. Ладно, через for переделаю.
#268 #434495
>>434493
ВАнгую, что афтар ошибся.

Ты мне на >>434490 ответь.
#269 #434496
Бля, не ошибся он, да. Туплю по случаю сонливости.
>>434495-кун
#270 #434498
>>434494
Не надо ничего переделывать. Просто внутри foreach если ты хочешь изменить исходный массив, нужно к нему напрямую и обращаться. Допустим у нас есть массив array, мы хотим найти в нем значение яблоко и поменять на апельсин:
http://ideone.com/P2vSBh
#271 #434501
>>434498
А можешь идиоту показать как это в моем примере применить?
#272 #434506
>>434501
У тебя там уже for стоит.
#273 #434507
>>434501
Ну вообщем вот. Надеюсь суть ясна.
http://ideone.com/oMQ3EF
#274 #434516
>>434507
Во, огромное спасибо!
#275 #434527
>>434507
Это опять я. Не можешь подсказать, почему перед запятой пробел не убирается? Регулярка нормальная вроде.
11 Кб, 212x238
#277 #434544
Пиздец, как же вы заебали, сраные нытики, которые не могут разобраться с простейшими вещами и им всё надо посимвольно разжёвывать, гуглить не умеем, кодить не умеем, но я у мамки погромист, да пошли вы нахуй.
#278 #434546
>>434544
У ОПа пхп-тредов наконец-то бомбануло?
#279 #434553
HTML5+php+CSS+javascript. Подойдет для веб дизайнинга? И насчет литературы сразу. Посоветуйте книжку по HTML5. И не сложно ли будет новичку Р. Никсон "Создаем динамические веб-сайты с помощью PHP, MySQL, JavaScript, CSS и HTML5"? Вы ток не ругайтесь пацаны.
#280 #434565
>>434539
Немного подделал, но пробел ПЕРЕД запятой все равно не хочет убираться. Halp!
http://ideone.com/gJQ19o
#281 #434568
>>434565
$string = str_replace (" ,", ",", $string);
#282 #434575
>>434568
Не подойдет. Перед запятой может быть несколько пробелов.
#283 #434577
>>434575
>>434565
У меня вот так получилось.
http://ideone.com/vEW3Kp
#284 #434580
Спасибо. Понял свою ошибку.
#285 #434581
>>434580
А, там вместо + нужно звездочку поставить. Тогда все на ура пойдет.
#286 #434584
>>434581
И там не надо было все знаки препинания вставлять. В 3м примере неправильно программа работала.
#287 #434640
>>434206
>>434011

Теперь все стало запутанно: https://github.com/MindiMakridi/Students/blob/master/profile.php

Например, найди здесь место где выставляется токен для незарегистрированного пользователя?

Все должно быть проще. Мы в начале файла profile.php выставляем токен в куках, а если форма отправлена, то заодно сверяем его с данными из POST. То есть должно быть в одном месте написано createXsrfCookie и в одном проверка $_POST['token']==$token. А у тебя там все как-то хаотично раскидано.

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

И еще, я просил вместо явной передачи $report в URL передавать коды, чтобы нельзя было вывести произвольное сообщение на сайте.

Тем более что ты неправильно формируешь тут URL:

> $report = "Вы успешно зарегистрировались";


> header("Location: http://students.ru/profile.php?msg=$report");


В URL не может быть пробелов. Когда ты подставляешь какие-то данные в query string ты должен экранировать спецсимволы с помощью urlencode() которая заменяет спецсимволы, в том числе пробел, на коды со знаком процента.

Давай доделаем уже, там немного осталось.
#288 #434641
>>434206

Еще тут непраивльно:

> https://github.com/MindiMakridi/Students/blob/master/templates/header.html#L13


> <input type='hidden' name="<?=$token ?>">

#289 #434642
http://ideone.com/rMxp5s

Все получилось. В "действие1" в цикле for я не знал чего вставить, тупо сделал то же самое, что и в 5 строке.

Поправьте, если что через жопу.
#290 #434643
>>434206

Этот анон >>434214 правильно заметил ошибку.

>>434226

Мануал наверно: https://php.net/manual/ru/langref.php

> Особенно интересуют вопросы модели памяти, многопоточности, жизненного цикла приложения (инициализация, обработка HTTP-запросов, завершение работы) и, немного, как там устроена сборка


Чтобы писать сайтик, тебе это не понадобится. Но рассказать могу, почему нет.

PHP обычно работает либо как плагин (динамически подключаемая библиоетка) в составе веб-сервера (Апач), либо как отдельный процесс (php-fpm организует пул таких процессов, соединяющихся с фронтенд сервером по протоколу FastCGI). Обработка HTTP запросов реализована в интерпретаторе таким образом, что пришедший запрос разбирается и данные из него заполняют глобальные массивы вроде GET/POST/COOKIE до запуска скрипта. Таким образом, тебе не нужен громоздкий стек для примера запросов и разбора HTTP: этот функционал уже встроен. Глобальные массивы подробно описаны в документации.

Фреймворки предлагают ООП-обертки для этого, например Symfony 2 содержит компонент HttpFoundation предлагающий классы Request и Response, аналоги которых ты наверняка видел в ява-фреймворках.

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

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

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

В PHP также предельно упрощена конфигурация сервера: ты можешь просто создать файл, допустим hello.php и при обращении по адресу http;//example.com/hello.php сервер запустит твой скрипт. То есть создание нового обработчика сводится к созданию файла. Но фреймворки обычно используют единую точку входа (index.php), и систему роутинга, с которой ты тоже наверняка сталкивался в яве.

Я советую не писать с нуля, а использовать фреймворк, предлагающий готовые классы для реализации MVC приложения. Тебе может подойти Symfony 2: он хорошо организован, полностью сделан в ООП-стиле, хорошо документирован, включает в себя прекрасный шаблонизатор Twig (c синтаксисом питоновского jinja), ORM Doctrine 2 (похожий на Hibernate), роутер, поддержку конфиграции в YML, для него есть много готовых плагинов. Но он может быть сложен для начинающего, и требует времени на изучение.

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

Насчет сборки мусора, там 2 механизма: reference counting для типов без циклических ссылок и простой сборщик мусора для сборки того что не собралось при подсчете ссылок. Опять же, это описано в мануале: http://php.net/manual/ru/features.gc.php

Я на практике не сталкивался с какими-то пробелмами со сборкой мусора. Один скрипт на тяжелом фреймворке может в пике потреблять 20-30 Мб, если же брать простые случаи то выходит 3-5 Мб. Это на время обработки запроса, после обработки эта память может быть использована для других скриптов.
#290 #434643
>>434206

Этот анон >>434214 правильно заметил ошибку.

>>434226

Мануал наверно: https://php.net/manual/ru/langref.php

> Особенно интересуют вопросы модели памяти, многопоточности, жизненного цикла приложения (инициализация, обработка HTTP-запросов, завершение работы) и, немного, как там устроена сборка


Чтобы писать сайтик, тебе это не понадобится. Но рассказать могу, почему нет.

PHP обычно работает либо как плагин (динамически подключаемая библиоетка) в составе веб-сервера (Апач), либо как отдельный процесс (php-fpm организует пул таких процессов, соединяющихся с фронтенд сервером по протоколу FastCGI). Обработка HTTP запросов реализована в интерпретаторе таким образом, что пришедший запрос разбирается и данные из него заполняют глобальные массивы вроде GET/POST/COOKIE до запуска скрипта. Таким образом, тебе не нужен громоздкий стек для примера запросов и разбора HTTP: этот функционал уже встроен. Глобальные массивы подробно описаны в документации.

Фреймворки предлагают ООП-обертки для этого, например Symfony 2 содержит компонент HttpFoundation предлагающий классы Request и Response, аналоги которых ты наверняка видел в ява-фреймворках.

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

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

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

В PHP также предельно упрощена конфигурация сервера: ты можешь просто создать файл, допустим hello.php и при обращении по адресу http;//example.com/hello.php сервер запустит твой скрипт. То есть создание нового обработчика сводится к созданию файла. Но фреймворки обычно используют единую точку входа (index.php), и систему роутинга, с которой ты тоже наверняка сталкивался в яве.

Я советую не писать с нуля, а использовать фреймворк, предлагающий готовые классы для реализации MVC приложения. Тебе может подойти Symfony 2: он хорошо организован, полностью сделан в ООП-стиле, хорошо документирован, включает в себя прекрасный шаблонизатор Twig (c синтаксисом питоновского jinja), ORM Doctrine 2 (похожий на Hibernate), роутер, поддержку конфиграции в YML, для него есть много готовых плагинов. Но он может быть сложен для начинающего, и требует времени на изучение.

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

Насчет сборки мусора, там 2 механизма: reference counting для типов без циклических ссылок и простой сборщик мусора для сборки того что не собралось при подсчете ссылок. Опять же, это описано в мануале: http://php.net/manual/ru/features.gc.php

Я на практике не сталкивался с какими-то пробелмами со сборкой мусора. Один скрипт на тяжелом фреймворке может в пике потреблять 20-30 Мб, если же брать простые случаи то выходит 3-5 Мб. Это на время обработки запроса, после обработки эта память может быть использована для других скриптов.
#291 #434644
>>434226

Если есть какие-то конкретные вопросы, можешь задавать.

>>434249

> на запуске скрипта резервируется кусман памяти указанный в php.ini, при выходе за его пределы - рантайм иксепшн


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

> тот запускает php интерпретатор на каждый реквест в своём треде


Неверно, один процесс интерпретатора может обработать много запросов. Треды используются на winodws, на linux (подозреваю из-за того что там треды хуже работают) используются процессы-рабочие.

> С использованием php-fpm можно сделать так, чтобы инстансы пхп не запускались на каждый реквест, а висели и ждали запросов, но это посложнее.


Это называется слышал звон, да не знаю где он. С php-fpm модель та же самая, что и с Апачом, просто под Апачом PHP подключается в процесс сервера как динамическая библиотека и функции интерпретатора вызваются напрямую, а в случае с php-fpm он запущен как отдельный процесс и принимает запросы по FastCGI. По производительности разницы особой нет, php-fpm нужен например чтобы напрямую взаимодетсвтовать с nginx или любым другим fastCGI capable сервером.

>>434477

Я думаю, в любом случеа ты за выходные не перепишешь. Но если есть еще вопросы, я может быть могу что-то подсказать.
#292 #434646
>>434285

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

>>434374

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

> И где прочитать про то, для чего как и где следует использовать ООП?


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

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

>>434404

> with message 'The "/templates" directory does not exist.


Написано же, папка не существует.

Когда ты указываешь /templates то это значит абсолютный путь, то есть путь от корня файловой системы (на linux) или корня текущего диска (на windows). То есть папка вроде c:/templates. Тебе надо писать _ _ DIR _ _ . '/templates' — как-то так примерно.
#293 #434648
>>434404

Чтобы не было путаницы, шаблоны лучше называть x.twig или x.html.twig (так вроде принято в Симфони)

О! Я тут баг просмотрел, даже странно что мне это в глаза не бросилось.

> https://github.com/tokotun/matriculant/blob/master/app/Pager.php#L39


> '&userSearch=' . $this->userSearch .


Это баг. Когда ты вставляешь данные в Query string, ты должен экранировать специсмволы с помощью процентов (это делает функция urlencode). Иначе что делать если в userSearch окажется знак & или пробел?

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

'?a=' . urlencode($a) . '&b=' . urlencode($b)

Вот тут подробнее описано:

http://ru.wikipedia.org/wiki/URL#.D0.9A.D0.BE.D0.B4.D0.B8.D1.80.D0.BE.D0.B2.D0.B0.D0.BD.D0.B8.D0.B5_URL
http://php.net/manual/ru/function.urlencode.php

Но в твоем случае можно сделать еще умнее. В PHP есть стандартная функция для сборки query string из массива: http://php.net/manual/ru/function.http-build-query.php — используй ее.

Пройдись так же по коду и исправь если где-то еще есть этот баг. Ну и старайся использовать http_build_query в таких случаях.

Что-то я забыл сам про эту функцию и сразу не сказал.

И тут опечатка:

> header("Location: login.php?action=saved");


> if ($_GET['action'] == 'save'){


Надо проверять свой код.

А так, в остальном, все верно. У тебя неплохое мини-приложение в итоге поулчилось, и выглядит аккуратно, ну и надеюсь, что аналогичную задачу ты легко сможешь решить. Ну это так, была разминка, а теперь пора переходить к изучение фреймворков и библиотек.
#293 #434648
>>434404

Чтобы не было путаницы, шаблоны лучше называть x.twig или x.html.twig (так вроде принято в Симфони)

О! Я тут баг просмотрел, даже странно что мне это в глаза не бросилось.

> https://github.com/tokotun/matriculant/blob/master/app/Pager.php#L39


> '&userSearch=' . $this->userSearch .


Это баг. Когда ты вставляешь данные в Query string, ты должен экранировать специсмволы с помощью процентов (это делает функция urlencode). Иначе что делать если в userSearch окажется знак & или пробел?

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

'?a=' . urlencode($a) . '&b=' . urlencode($b)

Вот тут подробнее описано:

http://ru.wikipedia.org/wiki/URL#.D0.9A.D0.BE.D0.B4.D0.B8.D1.80.D0.BE.D0.B2.D0.B0.D0.BD.D0.B8.D0.B5_URL
http://php.net/manual/ru/function.urlencode.php

Но в твоем случае можно сделать еще умнее. В PHP есть стандартная функция для сборки query string из массива: http://php.net/manual/ru/function.http-build-query.php — используй ее.

Пройдись так же по коду и исправь если где-то еще есть этот баг. Ну и старайся использовать http_build_query в таких случаях.

Что-то я забыл сам про эту функцию и сразу не сказал.

И тут опечатка:

> header("Location: login.php?action=saved");


> if ($_GET['action'] == 'save'){


Надо проверять свой код.

А так, в остальном, все верно. У тебя неплохое мини-приложение в итоге поулчилось, и выглядит аккуратно, ну и надеюсь, что аналогичную задачу ты легко сможешь решить. Ну это так, была разминка, а теперь пора переходить к изучение фреймворков и библиотек.
#294 #434650
>>434206

У тебя тут есть та же ошибка что у tokotun:

> https://github.com/MindiMakridi/Students/blob/master/index.php#L105


> $searchLink = htmlspecialchars($currentPage) . "?order=" . htmlspecialchars($sort, ENT_QUOTES) . "&amp;direction=" . htmlspecialchars($order, ENT_QUOTES) . "&amp;search=" . htmlspecialchars($search, ENT_QUOTES);



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

$link = '...a=' . urlencode($a) . '&b=' . urlencode($b);

а уже потом через htmlspecialchars если их надо вывести в hTML коде:

$linkHtml = htmlspecialchars($link, ...);

Почитай

http://ru.wikipedia.org/wiki/URL#.D0.9A.D0.BE.D0.B4.D0.B8.D1.80.D0.BE.D0.B2.D0.B0.D0.BD.D0.B8.D0.B5_URL
http://php.net/manual/ru/function.urlencode.php

Также, я советую не писать это все руками, а взять готовую удобную функцию http://php.net/manual/ru/function.http-build-query.php которая берет массив и формирует из него query string (но htmlspecialchars она разумеется не делает).
#295 #434651
>>434408

Linux? Может быть прав нету? Надо дать права на папку и файлы в веб-директории чтобы пользователь веб сервера (обычно это www-data) мог их читать. Например, поставить 0777. То есть файлы ты наверно заливаешь от своего пользователя и другим их читать получается запрещено. Почитай про права в линуксе:

http://ru.wikipedia.org/wiki/Chmod
http://www.linuxcenter.ru/lib/books/kostromin/gl_04_05.phtml

>>434410

> <input type="text" readonly value="http://testhub/t/{{ id }}">


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

Насчет таблицы answer_attempts — тут конечно есть сложный вопрос, а что должно храниться в answer? Просто число, текст или может ссылка на вариант ответа? Потому что если есть возможность использовать внешние ключи и ссылки то это конечно лучше чем не использовать. И второй вопрос — а что, если после прохождения тест будет отредактирован, например удалены вопросы или варианты ответа? Изменены критерии оценки или правльные ответы? Удалятся ли результаты прохождения? Изменятся ли?

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

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

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

> Yii::$app->response->cookies->add(new \yii\web\Cookie([


> 'name' => "test[$testId][started]",


> 'value' => true


Лучше наверно 1 а не true, в куках же только строки можно хранить.

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

> возможно стоит просто добавить количество вопросов в таблицу,


> либо написать функцию мимо ActiveRecord, чтобы не брать весь массив ради одного количества



Есть такое http://stackoverflow.com/a/22752533 — это для Yii 1 правда

Там как я понимаю, есть либо метод count, либо можно SQL запросом сделать. Брать все записи ради подсчета действитеьно нехорошо как-то.

И есть вот такое: http://www.yiiframework.com/doc/guide/1.1/ru/database.arr#sec-9

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

> $question = Question::find()->where(['test_id' => $testId])->limit(1)->offset($questionNumber-1);


Тут нужен еще order by иначе не будет работать как задумано
#295 #434651
>>434408

Linux? Может быть прав нету? Надо дать права на папку и файлы в веб-директории чтобы пользователь веб сервера (обычно это www-data) мог их читать. Например, поставить 0777. То есть файлы ты наверно заливаешь от своего пользователя и другим их читать получается запрещено. Почитай про права в линуксе:

http://ru.wikipedia.org/wiki/Chmod
http://www.linuxcenter.ru/lib/books/kostromin/gl_04_05.phtml

>>434410

> <input type="text" readonly value="http://testhub/t/{{ id }}">


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

Насчет таблицы answer_attempts — тут конечно есть сложный вопрос, а что должно храниться в answer? Просто число, текст или может ссылка на вариант ответа? Потому что если есть возможность использовать внешние ключи и ссылки то это конечно лучше чем не использовать. И второй вопрос — а что, если после прохождения тест будет отредактирован, например удалены вопросы или варианты ответа? Изменены критерии оценки или правльные ответы? Удалятся ли результаты прохождения? Изменятся ли?

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

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

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

> Yii::$app->response->cookies->add(new \yii\web\Cookie([


> 'name' => "test[$testId][started]",


> 'value' => true


Лучше наверно 1 а не true, в куках же только строки можно хранить.

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

> возможно стоит просто добавить количество вопросов в таблицу,


> либо написать функцию мимо ActiveRecord, чтобы не брать весь массив ради одного количества



Есть такое http://stackoverflow.com/a/22752533 — это для Yii 1 правда

Там как я понимаю, есть либо метод count, либо можно SQL запросом сделать. Брать все записи ради подсчета действитеьно нехорошо как-то.

И есть вот такое: http://www.yiiframework.com/doc/guide/1.1/ru/database.arr#sec-9

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

> $question = Question::find()->where(['test_id' => $testId])->limit(1)->offset($questionNumber-1);


Тут нужен еще order by иначе не будет работать как задумано
#296 #434652
>>434410

Вот этот вот код

> $question = Question::find()->where(['test_id' => $attempt->test_id])->limit(1)->offset($questionNumber-1);


Явно надо это вынести в метод у модели (полуить N-й вопрос теста)

И сразу же там сделать подгрузку вариантов ответов, чтобы лишних SQL запросов не было. Надо будет кстати как-нибудь потом еще с включенным отладчиком посмотреть нет ли где проблемы N + 1 запроса (эта пробелма упомянута тут http://www.yiiframework.com/doc/guide/1.1/ru/database.arr#sec-3 )

> + $attemptAnswer = new AttemptAnswer( );


> + $attemptAnswer->link('attempt', $attempt);


> + $attemptAnswer->link('question', $question);


Подумай, не стоит ли это тоже сделать методов вроде такого:

$attemptAnswer = $attempt->createAnswerAttempt($question);
#297 #434653
>>434640

>найди здесь место где выставляется токен для незарегистрированного пользователя?


Стоп, а зачем токен незарегестрированому пользователю? У незарегистрированного пользователя нечего красть.

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


Но я же защитил, или так не правильно?
https://github.com/MindiMakridi/Students/blob/master/index.php#L25
#298 #434654
>>434424

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

>>434428

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

Так, задача решена верно, хотя exit в последних 3 случаях лишний— и без него будет работать.

В ОП-посте есть 2 книги, есть сайт phptherightway. Но я бы советовал больше упора сделать на практику — в ОП посте написано что учебник дает только основы и после него надо решать практические задачки на создание сайтов и приложений (там такие есть).
#299 #434656
>>434468

Там exit нужен так как if стоит отдельным блоком. Но в if в самом конце exit необязателен.

>>434458

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

Проще всего обработанные input складывать в новый массив и из него собирать результат.
#300 #434657
>>434481

> $roulette % 100000;


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

$x = $x % 10000;

Иначе результат просто отбрасывается, а переменная не меняется.

Это то же самое что написать например команду

2 + 2;

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

>>434483

Та же ошибка что и выше. Строка $roulette % 10 ничего не делает.

>>434486

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

В твоем коде так же опечатка в строке 14:

> for ($i = 0; i < sizeof($text),$i++{



>>434487

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

$x = $y % 10;

Этого достаточно
#300 #434657
>>434481

> $roulette % 100000;


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

$x = $x % 10000;

Иначе результат просто отбрасывается, а переменная не меняется.

Это то же самое что написать например команду

2 + 2;

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

>>434483

Та же ошибка что и выше. Строка $roulette % 10 ничего не делает.

>>434486

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

В твоем коде так же опечатка в строке 14:

> for ($i = 0; i < sizeof($text),$i++{



>>434487

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

$x = $y % 10;

Этого достаточно
#301 #434658
>>434494

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

>>434501

$c = [];

foreach ($a as $b) {
$c[] = $a;
}

>>434539

Тут ошибка в регулярке:

> PHP Warning: preg_replace(): Compilation failed: missing ) at offset 14 in /home/YttfOF/prog.php on line 30



там скобок не хватает.

>>434544

Но ты же ничего и не разжевываешь

>>434553

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

>>434565

> $reg2 = '#(" ")(,(" "))#';


Двойная кавычка значит искать двойную кавычку. Чтобы искать пробел пиши либо просто пробел либо \\s (\\s ищет не только пробелы но и переводы строк и некоторые другие редкоиспользуемые пробельные символы вроде \\t, \\v или \\f).
#301 #434658
>>434494

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

>>434501

$c = [];

foreach ($a as $b) {
$c[] = $a;
}

>>434539

Тут ошибка в регулярке:

> PHP Warning: preg_replace(): Compilation failed: missing ) at offset 14 in /home/YttfOF/prog.php on line 30



там скобок не хватает.

>>434544

Но ты же ничего и не разжевываешь

>>434553

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

>>434565

> $reg2 = '#(" ")(,(" "))#';


Двойная кавычка значит искать двойную кавычку. Чтобы искать пробел пиши либо просто пробел либо \\s (\\s ищет не только пробелы но и переводы строк и некоторые другие редкоиспользуемые пробельные символы вроде \\t, \\v или \\f).
#302 #434659
>>434565

Код потом покажи, когда доделаешь. тут явно нужна тщательная проверка.

>>434577

> а-я


Букву ё надо указзывать откдльно так как в юникоде она идет после а-я. То есть надо писать

[a-яё]

Посмотри сам: http://unicode-table.com/ru/#cyrillic

>>434642

Надо вывести общую сумму выплаченного по кредиту (должно быть около 61270)

> В "действие1" в цикле for я не знал чего вставить,


Можно ничего не вставлять если хочешь:

for ( ; $x < 10; $x ++) { .. }

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

>>434653

> У незарегистрированного пользователя нечего красть.


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

> Но я же защитил, или так не правильно?


Там еще в profile.php есть логаут
#302 #434659
>>434565

Код потом покажи, когда доделаешь. тут явно нужна тщательная проверка.

>>434577

> а-я


Букву ё надо указзывать откдльно так как в юникоде она идет после а-я. То есть надо писать

[a-яё]

Посмотри сам: http://unicode-table.com/ru/#cyrillic

>>434642

Надо вывести общую сумму выплаченного по кредиту (должно быть около 61270)

> В "действие1" в цикле for я не знал чего вставить,


Можно ничего не вставлять если хочешь:

for ( ; $x < 10; $x ++) { .. }

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

>>434653

> У незарегистрированного пользователя нечего красть.


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

> Но я же защитил, или так не правильно?


Там еще в profile.php есть логаут
#303 #434660
>>434653

То есть мне кажется, проще защитить обе формы, и редактирование, и добавление, и спать спокойно. А то завтра злоумышленник нам нарегистрирует кучу левых людей с реальных IP адресов. Надежнее все же защититься.И код проще получается.
#304 #434664
>>434219
На пхп редко пишут что-то серьезное. Если так и остаться пхпшником, то всю жизнь будешь писать гостевые и натягивать на джумлу. Шанс устроиться на нормальную работу с нормальными проектами и нормальной зарплатой - небольшой. Просто дело в том, что интересные вещи пишутся на других языках.
>>434418
>>434419
Ну, мне пока еще даже 20 нет, рано к успеху приходить. Очень недолго работал в вебговноконторе натягивал на джумлу. Сейчас чуть меньше полугода работаю в обычной джаваконторе, энтерпрайз, вся хуйня. Разница просто огромная, задачи разнообразные и интересные, приходится учить и использовать дохуя всяких технологий (задел на будущее хороший получается), клевый офис (футбол, иксбокс, бесплатный кофе и прочие плюшки). Вот только один минус - зарплата лично у меня сейчас такая же, как была бы в вебговноконторе, но это поправимо уходом в контору классом повыше, что я и планирую сделать через несколько месяцев, как наберусь опыта.

Про путь лениво все подробно расписывать. Купил книжку "Создаем динамические веб-сайты с помощью PHP, MySQL, CSS, JavaScript", прочитал ее, написал очень кривую и хуевую имиджборду открывающие и закрывающие теги в разных файлах и прочие радости. Потом в вузе C# был, ООП, вся хуйня. Некоторое время сидел и над шарпом, и над пхп, прочитал несколько умных статей, начал но дальше начала дело не пошло читать книжку по пхп Мэтта Зандстры, кстати, отличная книжка. Потом уже сам не помню почему подумал что надо чето уровнем повыше брать. Выбирал между джавой и сисярпом, выбрал первое, т.к. вакансий больше намного. В общем-то зная что-то одно из них, второе изучить недолго. Короче прочитал кусками первый том двухтомника Хорстманна по джаве и полное руководство Шилдта (ебать оно огромное, я наверное половину пропустил в нем). После такого объема информации у меня все в голове не уложилось, было дохуя пробелов, но я решил идти к успеху. Разослал письма в несколько контор, типа студент хочет стажироваться, в той где работаю сейчас пригласили на собеседование, им особо ничего сложного не надо было, спрашивали, умею ли в Swing, работу с бд и чето еще. Кстати со свингом так ни разу и не столкнулся на работе, лол. Дали тестовое задание, в котором было всего понемногу, и три дня срока. Я его начал делать только на второй день, за два дня в бешеном темпе закодил это все, вышло 1-1,5к строчек. Конечно косяки там были, как архитектурные, так и кодинговые, но в целом получилось довольно неплохо. Тут был мой эпичный фейл, что я до этого момента до сих пор нихуя не представлял себе про развертывание джава-приложений и послал в контору скомпилированный джарник без исходников, лол. Но в общем мне сказали, что все норм и я принят. На работе первые два месяца входил в курс дела, пиздецки тупил и заебывал тимлида дебильными вопросами. Если честно, сейчас тоже раз-два в день у него что-нибудь спрашиваю, но уже не такое очевидное и тупое, и мне кажется все так делают. Короче сейчас я познакомился с кучей базовых технологий (работа с БД, XML, сетью, узнал как использовать библиотеки, лол, понял что Apache Commons - это охуенно, и тд), и чувствую себя достаточно уверенно. Уровень наверное еще джуниор, но уже очень уверенный. Через полгода буду работать мидом в хорошей конторе и зарабатывать тыщ 25-30 (в мухосрани). Через года два понаеду в ДС 1/2/3 и устроюсь за 50-100к в какую-нибудь крутую контору, где надо говорить голосом по английски с заказчиками и прочие радости жизни.

Надеюсь кому-то это интересно и не зря катал эту простыню, (смех)
#304 #434664
>>434219
На пхп редко пишут что-то серьезное. Если так и остаться пхпшником, то всю жизнь будешь писать гостевые и натягивать на джумлу. Шанс устроиться на нормальную работу с нормальными проектами и нормальной зарплатой - небольшой. Просто дело в том, что интересные вещи пишутся на других языках.
>>434418
>>434419
Ну, мне пока еще даже 20 нет, рано к успеху приходить. Очень недолго работал в вебговноконторе натягивал на джумлу. Сейчас чуть меньше полугода работаю в обычной джаваконторе, энтерпрайз, вся хуйня. Разница просто огромная, задачи разнообразные и интересные, приходится учить и использовать дохуя всяких технологий (задел на будущее хороший получается), клевый офис (футбол, иксбокс, бесплатный кофе и прочие плюшки). Вот только один минус - зарплата лично у меня сейчас такая же, как была бы в вебговноконторе, но это поправимо уходом в контору классом повыше, что я и планирую сделать через несколько месяцев, как наберусь опыта.

Про путь лениво все подробно расписывать. Купил книжку "Создаем динамические веб-сайты с помощью PHP, MySQL, CSS, JavaScript", прочитал ее, написал очень кривую и хуевую имиджборду открывающие и закрывающие теги в разных файлах и прочие радости. Потом в вузе C# был, ООП, вся хуйня. Некоторое время сидел и над шарпом, и над пхп, прочитал несколько умных статей, начал но дальше начала дело не пошло читать книжку по пхп Мэтта Зандстры, кстати, отличная книжка. Потом уже сам не помню почему подумал что надо чето уровнем повыше брать. Выбирал между джавой и сисярпом, выбрал первое, т.к. вакансий больше намного. В общем-то зная что-то одно из них, второе изучить недолго. Короче прочитал кусками первый том двухтомника Хорстманна по джаве и полное руководство Шилдта (ебать оно огромное, я наверное половину пропустил в нем). После такого объема информации у меня все в голове не уложилось, было дохуя пробелов, но я решил идти к успеху. Разослал письма в несколько контор, типа студент хочет стажироваться, в той где работаю сейчас пригласили на собеседование, им особо ничего сложного не надо было, спрашивали, умею ли в Swing, работу с бд и чето еще. Кстати со свингом так ни разу и не столкнулся на работе, лол. Дали тестовое задание, в котором было всего понемногу, и три дня срока. Я его начал делать только на второй день, за два дня в бешеном темпе закодил это все, вышло 1-1,5к строчек. Конечно косяки там были, как архитектурные, так и кодинговые, но в целом получилось довольно неплохо. Тут был мой эпичный фейл, что я до этого момента до сих пор нихуя не представлял себе про развертывание джава-приложений и послал в контору скомпилированный джарник без исходников, лол. Но в общем мне сказали, что все норм и я принят. На работе первые два месяца входил в курс дела, пиздецки тупил и заебывал тимлида дебильными вопросами. Если честно, сейчас тоже раз-два в день у него что-нибудь спрашиваю, но уже не такое очевидное и тупое, и мне кажется все так делают. Короче сейчас я познакомился с кучей базовых технологий (работа с БД, XML, сетью, узнал как использовать библиотеки, лол, понял что Apache Commons - это охуенно, и тд), и чувствую себя достаточно уверенно. Уровень наверное еще джуниор, но уже очень уверенный. Через полгода буду работать мидом в хорошей конторе и зарабатывать тыщ 25-30 (в мухосрани). Через года два понаеду в ДС 1/2/3 и устроюсь за 50-100к в какую-нибудь крутую контору, где надо говорить голосом по английски с заказчиками и прочие радости жизни.

Надеюсь кому-то это интересно и не зря катал эту простыню, (смех)
#305 #434671
>>434651
Нет, Windows.
#306 #434718
ОПчик, оцени код.
http://ideone.com/bsQgpP
sage #307 #434720
>>434718
Пиздец говнище, даже беглого взгляда стало достаточно.
#309 #434725
>>434720

>я сажамен я спешу на помощ!!!))))

#310 #434726
>>434718
Неплохо, а вообще мне кажется вместо реверса можно шафл использовать http://php.net/manual/ru/function.shuffle.php тогда результат будет не предсказуемым.
мимо не ОП
#311 #434731
>>434726
Я тоже в начале шафл поставил. Потом задачку повнимательнее прочитал, а там надо чтобы в обратном порядке слова стояли.
#312 #434739
Помогите разобраться с ошибками в пхп, пожалуйста, а то я совсем запутался. Вот как я это понимаю:

У нас есть две сущности ошибка и исключение. Ошибок есть куча видов: всякие notice, warning, eerror. Исключения можно отлавливать через try ... catch, а ошибки - нет. Можно отлавливать ошибки через функцию переданную в set_error_handler, кидая внутри неё исключение, а потом обрабатывая его, делая вид что кидается не какой-нибудь notice, а исключение.

Правильно ли я понял? И ещё:

set_error_handler не перехватывает сами исключения?

Почему в примере #1 здесь http://php.net/manual/ru/function.set-error-handler.php есть "!(error_reporting() & $errno)". Получается так, что $errno может становиться false и это значит, что ошибки нет? Почему тогда функция из set_error_handler вообще вызывается если ошибки нет?
#313 #434749
Реквестирую книгопечатной литературы по пхп. И вообще неплохо бы было книжек по всему что необходимо для создания с нуля. Типа разметочка, ява скрипты, css.
231 Кб, 540x764
#314 #434754
Супец, ананасы.
Я — простая js-макака, с php знаком на уровне написания тем для wordpress.
Нужен простой php движок, желательно на файлах, потому что нет желания редактировать контент в базе.
Искаропки должны быть:
1. ЧПУ
2. Отправка писем Я как-то наебался с phpmailer, больше не хочу
3. Простая админка для редактирования контента.
#315 #434759
>>434664
Да, интересно, и ты молодец.
10 Кб, 745x637
#316 #434760
#317 #434769
>>434754

>нет желания редактировать контент в базе


А, ну раз так... У меня нет желания тебе советовать.
#318 #434770
>>434769

>ухх сажамен под масикровкой)))))

#319 #434780
Функции, косяков нету?

http://ideone.com/bhEqwL
#320 #434801
>>434754

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


Ты с этим завязывай
#321 #434836
>>434801
>>434769
Ну ок, давайте что там у вас есть с mysql
12 Кб, 1230x239
#322 #434860
Столкнулся с очередной напастью. Думаю это из-за того, что я вручную подредактировал один файл на гитхабе. Теперь вот почему-то выдает ошибку, хотя этого файла даже в коммите нету.
#323 #434864
https://github.com/MindiMakridi/Students
Вот, очередная порция фиксов. Есть правда еще непонятки:
>>434640

>И еще, я просил вместо явной передачи $report в URL передавать коды, чтобы нельзя было вывести произвольное сообщение на сайте.


Вот этот момент не совсем понятен.
#324 #434888
>>434860
А есть более нормальные клиенты с GUI для работы с гитом?

Например как на битбаките TortouseHg?
#325 #434900
Пытаюсь обкатать PDO, "подключаюсь" к БД и... ничего. В ответ на exec или quote хорошо если эскуэльный запрос выплюнет в его первозданном виде, а то и вовсе пусто. Что за бяка и куда копать?
#326 #434901
<?php

error_reporting(-1);

echo "Бросаем кубик.../n";

$random = 0; /куда лепить функцию mt_rand()?/

echo "Выпало $random\n";

?>
#327 #434905
>>434860
По скрину непонятно где ошибка. Алсо, когда ты редактируешь файл на гитхабе, это коммит. Потом надо сделать pull -r локально
#328 #434911
>>434900

>>http://pastebin.com/ZENrkDAu


Код.
Сейчас срабатывает die('ERROR'), стоящий рядом с $db->query
#329 #434924
>>434900
Разобрался сам, всем спасибо за внимание
#330 #434949
>>434901
<?php
error_reporting(-1);
echo "Бросаем кубик.../n";
$random = mt_rand(1,6);
echo "Выпало $random\n";
?>

Вот как-то так.
#331 #434980
>>434860

Сделай git status (я не знаю, есть ли это в GUI, если нет то сделай в консоли). Он пишут что у тебя есть незакомиченные изменения и надо либо их закомиттить либо отменить а только потом синхронизироваться.

Кстати, ты изучал работу с git в консоли? Начинающим надо именно там учитьяс, прочесть git book и сделать то что там описывается, а потом переходить к GUI программам.
#332 #434981
>>434888

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

А вообще есть куча клиентов: http://git-scm.com/download/gui/linux
#333 #434982
>>434980
Я начал читать, но у меня как то не задалось с командной строкой с самого начала. Во первых сама директория для гита установилась по умолчанию в мои документы. Я удалил её оттуда и перенес в папку моего проекта, но он там (в моих документах) заново появился. Поэтому у меня теперь как бы два директории с гитом, и командная строка видит по умолчанию ту, что в моих документах.
#334 #434983
>>434864

Ты передаешь в URL текст сообщения. Любой может туда подставить свое сообщение и оно выведется на сайте при открытии ссылки. Например, злоумышленник делает ссылку http://example.com/profile.php?msg=(для подтверждения регистрации заплатите 100 биткойнов на кошелек X) и каким-то образом подсовывает пользователю, и тот может поверить так как сообщение выводится на официальном сайте.

Это может использоваться для мошенничества, например.

Если использовать коды вроде ?msg=saved то подставить любое сообщение не получится. Да и ссылка будет короче.
#335 #434984
>>434983
Я понял в чем там проблема, мне не понятно, как именно её решить (кроме костыля с регулярками)
#336 #434986
>>434984
А, хотя, до меня вроде дошло. Через if или switch, проверять значение переменной и выводить сообщение в зависимости от значения get переменной.
#337 #434990
>>434900

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

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

$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

Мануал: http://php.net/manual/ru/pdo.error-handling.php

Проверить что все работает можно выполнив неправильный запрос например "SDASDADAA"

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

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

- ошибки сохраняются в лог ошибок. Можно открыть его и почитать. Если ты запускаешь код на локалхосте, у себя, то лог хранится в папке Апача (обычно она называется logs) и имеет название вроде error.log (в линуксе в папку /var/log/apache2 ). Если на хостинге — там либо есть файл error.log либо раздел в панели управления, где лог можно посмотреть

- также, ты можешь включить отображение ошибок. Открой файл php.ini, поставь там display_errors = On и error_reporting = E_ALL и перезапусти сервер. Теперь ошибки должны выводиться на экран.

Проверить, работает ли вывод ошибок, можно запустив скрипт содержающий обращение к несуществующей переменной вроде echo $sdgasdad; и проверив, выведется ошибка или нет. Если все верно, то должна вывестись.

Ну и убери try/catch — он не нужен. Я знаю, что в некоторых учебниках и статьях есть такой код, он абсолютно неправильный и вредный. Почему:

- в PHP есть встроенный механизм обработки, логгирования и вывода исключений. Этот код его заменяет на вывод на экран, что не всегда требуется
- при этом способе пользователю при ошибке показывается непонятное и не нужное ему сообщение, в то время как в логи на сервере ничего не запишется и ты об ошибке не узнаешь. А надо делать ровно наоборот.
- исключение и так выведется на экран если у тебя display_errors = On

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

Вот мой мини-урок про исключения: https://gist.github.com/codedokode/65d43ca5ac95c762bc1a
#337 #434990
>>434900

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

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

$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

Мануал: http://php.net/manual/ru/pdo.error-handling.php

Проверить что все работает можно выполнив неправильный запрос например "SDASDADAA"

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

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

- ошибки сохраняются в лог ошибок. Можно открыть его и почитать. Если ты запускаешь код на локалхосте, у себя, то лог хранится в папке Апача (обычно она называется logs) и имеет название вроде error.log (в линуксе в папку /var/log/apache2 ). Если на хостинге — там либо есть файл error.log либо раздел в панели управления, где лог можно посмотреть

- также, ты можешь включить отображение ошибок. Открой файл php.ini, поставь там display_errors = On и error_reporting = E_ALL и перезапусти сервер. Теперь ошибки должны выводиться на экран.

Проверить, работает ли вывод ошибок, можно запустив скрипт содержающий обращение к несуществующей переменной вроде echo $sdgasdad; и проверив, выведется ошибка или нет. Если все верно, то должна вывестись.

Ну и убери try/catch — он не нужен. Я знаю, что в некоторых учебниках и статьях есть такой код, он абсолютно неправильный и вредный. Почему:

- в PHP есть встроенный механизм обработки, логгирования и вывода исключений. Этот код его заменяет на вывод на экран, что не всегда требуется
- при этом способе пользователю при ошибке показывается непонятное и не нужное ему сообщение, в то время как в логи на сервере ничего не запишется и ты об ошибке не узнаешь. А надо делать ровно наоборот.
- исключение и так выведется на экран если у тебя display_errors = On

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

Вот мой мини-урок про исключения: https://gist.github.com/codedokode/65d43ca5ac95c762bc1a
#338 #434998
>>434982

Тебе надо было писать в наш тред и задавать вопросы, я бы ответил.

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

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

Вот простой гайд по командной строке (windows/linux), там описано как сменить директорию: https://gist.github.com/codedokode/10539568

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

Если у тебя будут еще какие-то вопросы, задавай. Лучше разобраться чем каждый раз все делать наугад и сломать в итоге репозиторий — ты больше времени на исправление потратишь.
#339 #435000
>>434986

Либо как вариант можно сделать массив:

$x = array(
'saved' => 'Все сохранено',
...
);
#340 #435002
>>434998

>командная строка


Я имел ввиду консоль гита, конечно же.
#341 #435024
>>435002

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

Ну и если речь про msysgit под windows то там есть Git bash — это портированный на Windows bash (командная оболочка в линуксе) потому если у тебя консоль гита напоминает пикрелейтед https://msysgit.github.io/img/gw1.png то читай ту часть урока которая описывает командную строку в линуксе.
#342 #435025
>>435002

То есть в Msysgit «консоль git» или git bash это просто портированный на Windows аналог командной строки из linux (в котором доступен git и базовые линуксовые команды вроде cd, less, и т.д.).
#343 #435034
>>434949
Спасибо анончик протрезвев допер.
#344 #435035
Няши, подскажите, почему ошибку выдает?
http://ideone.com/wdVVJX
#345 #435056
>>435035
Он тебе пишет что нет такого элемента в массиве. Алсо, проверят счетчик на соответствие какому-то интервалу с помощью регулярок - забивать гвозди микроскопом.
#346 #435065
>>434739

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

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

Вот директивы разрешающие запись в лог и вывод на экран:

http://php.net/manual/ru/errorfunc.configuration.php#ini.display-errors
http://php.net/manual/ru/errorfunc.configuration.php#ini.log-errors
http://php.net/manual/ru/errorfunc.constants.php

(до 5.4 в E_ALL входили не все виды ошибок и кто-то даже хотел ввести константу E_REALLY_ALL)

Что особо печально, через php.ini директивой error_reporting можно включить режим игнорирования некоторых видов ошибок (мануал: http://php.net/manual/ru/errorfunc.configuration.php#ini.error-reporting ). По умолчанию игнорирование отключено, но многие криворукие программисты разрабатывали свои продукты под настройку, что нотисы и варнинги игнорируются (то есть они писали кривой код и просто скрывали варнинги).

Фатальные ошибки в отличие от варнингов и нотисов завершают скрипт.

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

Ты можешь ловить ошибки назначив свою функцию-обработчик (это наызвается неструктурная обработка ошибок, неструктурная потому что ты не указываешь в какой области ловить ошибки и какого типа - ловится все). В этом случае стандартные механизмы (запись в лог/вывод на экран) отключаются. мануал: http://php.net/manual/ru/function.set-error-handler.php

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

Если тебе не хочется возиться с обработкой ошибок и хочется перевести все на исключения (тебе должно хотеться), в php предусмотрен стандартный класс для превращения всех ошибок (кроме фатальных) в исключения: http://php.net/manual/ru/class.errorexception.php

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

Про исключения у меня есть мини-урок: https://gist.github.com/codedokode/65d43ca5ac95c762bc1a

Теория про структурную/неструктурную обработку исключений: https://ru.wikipedia.org/wiki/%D0%9E%D0%B1%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%BA%D0%B0_%D0%B8%D1%81%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D0%B9

> Можно отлавливать ошибки через функцию переданную в set_error_handler, кидая внутри неё исключение, а потом обрабатывая его, делая вид что кидается не какой-нибудь notice, а исключение.


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

> set_error_handler не перехватывает сами исключения?


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

> Получается так, что $errno может становиться false и это значит, что ошибки нет? Почему тогда функция из set_error_handler вообще вызывается если ошибки нет?


Это нужно для того чтобы поддерживалась настройки error_reporting (которая позволяет игнорировать некоторые виды ошибок) и оператор тишины @: http://php.net/manual/ru/language.operators.errorcontrol.php

Если убрать if то @ и настрйока error_reporting не будут учитываться и все виды ошибок будут становитьяс исключениями, даже если они подавлены через @. Это не всегда хорошая идея, иногда @ необходима (там есть пара функций).
#346 #435065
>>434739

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

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

Вот директивы разрешающие запись в лог и вывод на экран:

http://php.net/manual/ru/errorfunc.configuration.php#ini.display-errors
http://php.net/manual/ru/errorfunc.configuration.php#ini.log-errors
http://php.net/manual/ru/errorfunc.constants.php

(до 5.4 в E_ALL входили не все виды ошибок и кто-то даже хотел ввести константу E_REALLY_ALL)

Что особо печально, через php.ini директивой error_reporting можно включить режим игнорирования некоторых видов ошибок (мануал: http://php.net/manual/ru/errorfunc.configuration.php#ini.error-reporting ). По умолчанию игнорирование отключено, но многие криворукие программисты разрабатывали свои продукты под настройку, что нотисы и варнинги игнорируются (то есть они писали кривой код и просто скрывали варнинги).

Фатальные ошибки в отличие от варнингов и нотисов завершают скрипт.

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

Ты можешь ловить ошибки назначив свою функцию-обработчик (это наызвается неструктурная обработка ошибок, неструктурная потому что ты не указываешь в какой области ловить ошибки и какого типа - ловится все). В этом случае стандартные механизмы (запись в лог/вывод на экран) отключаются. мануал: http://php.net/manual/ru/function.set-error-handler.php

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

Если тебе не хочется возиться с обработкой ошибок и хочется перевести все на исключения (тебе должно хотеться), в php предусмотрен стандартный класс для превращения всех ошибок (кроме фатальных) в исключения: http://php.net/manual/ru/class.errorexception.php

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

Про исключения у меня есть мини-урок: https://gist.github.com/codedokode/65d43ca5ac95c762bc1a

Теория про структурную/неструктурную обработку исключений: https://ru.wikipedia.org/wiki/%D0%9E%D0%B1%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%BA%D0%B0_%D0%B8%D1%81%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D0%B9

> Можно отлавливать ошибки через функцию переданную в set_error_handler, кидая внутри неё исключение, а потом обрабатывая его, делая вид что кидается не какой-нибудь notice, а исключение.


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

> set_error_handler не перехватывает сами исключения?


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

> Получается так, что $errno может становиться false и это значит, что ошибки нет? Почему тогда функция из set_error_handler вообще вызывается если ошибки нет?


Это нужно для того чтобы поддерживалась настройки error_reporting (которая позволяет игнорировать некоторые виды ошибок) и оператор тишины @: http://php.net/manual/ru/language.operators.errorcontrol.php

Если убрать if то @ и настрйока error_reporting не будут учитываться и все виды ошибок будут становитьяс исключениями, даже если они подавлены через @. Это не всегда хорошая идея, иногда @ необходима (там есть пара функций).
#347 #435066
>>434739

Если тебе еще что-то непонятно, задавай вопросы.

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

Не забывай что при установке обработчика обязанность логгировать ошибку ложится на тебя.
#348 #435067
>>434754

Вордпресс может быть? К нему плагинов куча, админка есть.
#349 #435072
>>435056
Через массив чисел лучше проверять?
#350 #435075
>>431924
Здравствуйте, я в общем-то к вам по такому вопросу. Научите меня пилить гостевуху на пхп. Сделал по гайду не получилось. Нужно комменты в текстовый файл записывать, а потом выводить (read, write?) или нужно это делать в базу данных?
#351 #435079
>>435075
Вот смотри, как я свою первую сделал за час

два файла в ней и база данных.

http://ideone.com/GrkT0S

http://ideone.com/XnKNy8

Сам попробуй разобраться, так как я ухожу.

Алсо может аноны оценят мой говнокод.
#352 #435128
Задание про кредит:
http://ideone.com/HtuwTe

Говнокод еще тот, да.
#353 #435131
Вторая задачка про вклад:
http://ideone.com/0WJq2h

Очень печально, что я не могу составить сразу схему всего скрипта в голове - оно само появляется по ходу написания кода.
#354 #435132
>>435131
и не не обязательно составлять в голове. можешь письменно описать на листочке.
#355 #435136
>>435132

Лучше нарисовать, квадратиками и стрелочками наверно. Да вообще, поначалу задачи простые, пиши как получается, и вкидывай в тред.
#356 #435137
>>435128
А вот и не правильно.
Когда у тебя как только остаётся на счету меньше 5000, школьник тут же неизвестно откуда достаёт ещё денег, что бы остатки погасить долг.
Хотя в задаче ясно сказано 5000 в месяц это всё что емё даёт мама.

Ещё >echo "12 месяц спустя: Кредит покрыт,
Это то же костыль. Тут у тебя не зависимо от того сколько анон брал кредита будет написано, что кредит он покрыл 12 месяцев спустя.
#358 #435139
#359 #435206
>>435065
>>435066
Спасибо большое, разобрался.
31 Кб, 1366x679
#360 #435229
>>435139
Ты смог разобраться в моем говне? В общем что бы это работало тебе еще нужно базу данных прикрутить. У меня там 1 таблица "posts", в ней
столбцы id, message, name, posttime.
id - накручиваются автоматически, заюзано autoincrement
message заносится из $_POST['text'];
name соответственно из name, ели пользователь оставил пустым то пишется Аноним.
Время вроде бы само заполняется, когда пост кидается в базу, то автоматом туда шлепается timestamp, потом берется и показывается у каждого поста.

Выглядит в итоге все пикрилейтед. Скажите аноны, рано еще джуном идти с такой хуетой? >>435079
#361 #435232
Я алкоголик и это мне мешает заниматься PHP.
#362 #435236
https://github.com/MindiMakridi/Students
Это опять я со своим многострадальным проектом.
#363 #435248
>>434190

Спасибо.
Ладно, первые вопросы справедливы, спасибо.
Ну я так понимаю, подобное можно вычитать в книге "PHP Собеседование в вопросах и ответах", да?
А вопросы с подвохом? Это ведь шуточки про hr, да?
Это вот всё на стажера нужно?
В резюме про что писать-то?
#364 #435253
>>434190

>что выведет код var_dump("x" == 0) ?


Сейчас проверил и удивился, если честно. 0 ведь эквивалентен false, а строка true. Но var_dump("x" == 0) почему-то выводит true.
102 Кб, 597x479
#365 #435257
>>435248
С подвохом вопросы — прямо с собеседования убегать надо это когда, падаван юный.
#366 #435259
>>435257

Я имел ввиду ненормальные вопросы, просто в глаза поебался. Ты тоже про них?
#367 #435262
Ятуп, не знаю как решить задачку с пекой. Подскажите хотя бы как сделать правильно.
Вот что я наделал:
https://ideone.com/aY91Dy
#368 #435269
>>435262
У тебя break; стоит в самом цикле, а не внутри условия которое его должно прекращать например.
Стало быть в процессе первой итерации он у тебя и прекращается.
#369 #435288
Оп-кун, а что есть годного по jquery, прошел курс на codecademy, но он кроме примитивного движения, затемнить, поменять css эффекты и т.п. не научил.
#371 #435299
Кто хорошо знаком с sql, поясните мне за 6е упражнение на
http://sql-ex.ru
Я чет из-за него дропнул его пару месяцев назад, но сейчас после продолжительного ебланства решил взять себя в руки и прочитав к упражнению материал:
http://www.sql-tutorial.ru/ru/book_explicit_join_operations/page1.html

составил вот такой вот запрос:

SELECT product.maker, laptop.speed
FROM product INNER JOIN laptop
ON product.model = laptop.model
WHERE laptop.hd >= 10.0

но хоть оно и дает верные результаты, все равно не нравится сайту и кидает меня на faq: http://www.sql-tutorial.ru/book_exercise_6.html
В нем не могу понять объяснение.

Кто может пояснить что не так?
#372 #435331
>>435299

>На этой неделе сертификаты получили:


>Михайлов Н.А. (Nikitos777)


>Nikitos777


(Смех).
#373 #435340
Привет, аноны. Как делается авторизация пользователя в rest api ?
Есть какие-то общие рекомендации, ну или готовые решения? Интересует не сам механизм, а правильная реализация. Я делаю просто. ТЫ ему логин-пароль, он тебе в ответ случайную строку (токен). Далее все запросы в связке логин+токен.
Так вот меня настораживает тот факт, что практически все крупные api (amazon s3) используют заголовки, для передачи токена, логина. В php же так просто заголовок и не прочитаешь, нужно перебирать массив $_SERVER. В правильном ли я направлении?
#374 #435350
Анон поясни в чем проблема?
http://ideone.com/xyjgRq
#375 #435351
>>435350
Забыл точку с запятой поставить.
#376 #435352
>>435351
Боже я аутист не заметил спасибо
#377 #435358
Антуаны поясните как увеличить время на работу программы код вроде правильный http://ideone.com/xyjgRq
#378 #435380
#379 #435386
>>435340

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

Можно посмотреть в сторону OAuth/OAuth2, может быть можно использовать их? Там как раз токены есть.

Имей также в виду, что сам по себе REST идеальная абстракция, и реальные его имплементации могут не соответствовать ему на 100%.

Посмотри как сделана авторизация в других АПИ:

Google использует Oauth2 (раньше использовали велосипед): https://developers.google.com/accounts/docs/OAuth2

Яндекс использует Oauth: https://tech.yandex.ru/webmaster/doc/dg/concepts/About-docpage/

https://tech.yandex.ru/disk/api/concepts/quickstart-docpage/
#380 #435388
>>435340

> В php же так просто заголовок и не прочитаешь, нужно перебирать массив $_SERVER


Ничего перебирать не надо. Все заголовки есть в _SERVER, это описано в документации. А если ты используешь фреймворк то там скорее всего есть объект Request.

> Далее все запросы в связке логин+токен.


Логин тут лишний
#381 #435390
>>435288

Есть неплохие задачи на jQUery из нашего сборника задач на JS: https://gist.github.com/codedokode/ce30e7a036f18f416ae0#dom--jquery

Имей в виду что для их решения надо знать DOM. Если ты не знаешь DOM то ты все равно вряд ли нормально сможешь пользоваться jQuery.
#382 #435413
В общем я попытался сделать комменты вот из этого места http://ideone.com/GrkT0S. Создал базу данных на хостингере - все норм. Но вот на этой строчке выдает ошибку, что делать?

$headersNumber = $queryResult -> num_rows;
#383 #435414
>>435413
А какой код ошибки или что-то типа того? Ты на попробовал сначала на локальной машине устаносить php + mysql и на ней запустить?
#384 #435430
>>433859
Спасибо, анон.
#385 #435438
>>435414
пхп у меня на локалке установился, а вот с мскл проблема. там настроек куча, нужно в километровых текстовых файлах рыться, и вообще я по-моему их много наустанавливал и хз, как и откуда удалять. так что пилю на хосте.

И вот я создал на хосте свою БД с именем пользователя, паролем, названием базы. Пытаюсь такой функцией вывести лист ДБ и вот что выводит. Что это значит? Там эта функция запрещена?

$link = mysqli_connect('localhost','юзернейм','пароль');
$db_list = mysql_list_dbs($link);

while($row=mysql_fetch_object($db_list))
{
echo $row->Database . "\n";
}

Warning: mysql_list_dbs() has been disabled for security reasons in /home/u209251236/public_html/php/index.php on line 15

Warning: mysql_fetch_object(): supplied argument is not a valid MySQL result resource in /home/u209251236/public_html/php/index.php on line 17
#386 #435446
>>435438 Либо у тебя ругается на ненастроенную на хостинге MySQL, либо там вообще тчо-то неподдерживается, что вполне вероятно из-за бесплатности. Ну и у тебя база то пустая похоже, в ней нужно еще создать табличку правильную, что бы все заработало. Я не средствами php её сделал, а вручную, перед тем как с базой работать. Думал что ты тоже справишься, но я не уверен что дело именно в этом. Вот тебе в общем "дамп" моей базы http://rghost.ru/private/6pCN2XTBD/d3e899e5fc1abcd310b3ae7891ccaacd

Алсо попробуй установить для начала просто сборку типа Денвера: http://www.denwer.ru/ или EasyPHP: http://www.easyphp.org/

Далее заходишь в phpmyadmin, который входит в обе сборки, создаешь там базу с таким же именем пустую, после чего жмешь импортировать, и вставляешь из этого файла. Не забудь только подогнать везде пользователя и пароль к одному виду. Что бы в mysql у тебя был пользователь root без пароля, если ты ничего не менял в .php файлах, либо в этой строчке поменяй под своё:

>$db = array('host' => 'localhost', 'user' => 'root', 'pass' => '', 'name' => 'microboard');



Если сборки будут ругаться на занятый 80-й порт, то попробуй скайп выключить перед запуском, как-то так.
#387 #435449
>>435438
Теперь по функциям

>$db_list = mysql_list_dbs($link);


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

>$link = mysqli_connect('localhost','юзернейм','пароль');


сработало, то уже все норм, вроде, но ты можешь отправить туда запрос в духе:
$result = mysqli_query($link, "SHOW DATABASES");

Алсо mysql_... является устаревшей библиотекой и все такое, может быть ругается по этому
Минимум попробуй найти альтернативу в mysqli_...

Warning: mysql_fetch_object(): supplied argument is not a valid MySQL result resource in /home/u209251236/public_html/php/index.php on line 17
Пишет что переданый в него ресурс неправилен, очевидно что ничего не работает, так как в него у тебя передается результат предыдущей функции, которая тоже не выполнена.

Еще у тебя идут мешанина из mysql и mysqli, возможно проблема в этом, никогда так не делал, но думаю что они могут конфликтовать.
Твой $link законнекченный через mysqli не подходит для работы с mysql, надеюсь понятно объясняю.
#388 #435466
>>431924
Здарова, макаки!
Стоит ли начинать учить РНР в 2015 почти с нуля? Под почти я подразумеваю наличие знаний о том, что такое переменная, массивы, циклы и т.д., в общем те начальные знания, что можно получить на каких-нибудь курсах codecademy по другим языкам.

И второй вопрос. РНРшников очень много, ОЧЕНЬ, т.е. на зп в 50-60к можно рассчитывать только если станешь убер синьёром лет через 20?
#389 #435487
>>435466
У нас тут пхпшник на 100к сидит. Надо бы тоже попросить что ли побольше бабла
#390 #435508
>>435466
В ДС 50-60к это уровень через год работы максимум если с полного нуля
#391 #435511
>>435466
В мухосрани самое большее, на что может рассчитывать пхпшник - 30к и то с потом и кровью.
#392 #435514
>>435511
В офисе, ты имел ввиду
#393 #435518
>>435514
Ну да, а есть еще какие-то варианты?
#394 #435519
>>435508
Тоесть с момента открытия книги "делаем динамические сайты с помощью пхп, хтмл и цсс", при добросовестном обучении, через год можно будет работать за 50к в Москве?
#395 #435520
Кто-нибудь может разъяснить по устройству на удалёночку в забугорную компанию? В Европу или США. Какие для них могут быть загвоздки, если я не гражданин их страны, и какие для меня. Точно знаю, что некоторые из UK работают удалённо на USA, и из Канады тоже.
#396 #435521
>>435520
Нашел где спросить.
#397 #435522
>>435519
Лучше книгу это не читать, а делать учебник ОПа. В остальном да.
>>435518
Действительно, какие
#398 #435528
>>435380
Не понадобилось ошибка в коде была
#399 #435531
>>434200

Странное какое-то описание:

> 6.1 Тред, который подлежит удалению, переносится в nosql базу, где...


Такое ощущение что этот пункт доавлен только ради того чтобы использовать nosql базу.Чем SQL база не годится?

Насчет последних постов, чтобы выбирать их эффективно, надо в треде хранить ссылки на них. Можно сделать это реляцияонно, то есть таблицей связи latest_posts c колонками (thread_id, post_id, sort), можно нереляционно, храня id через запятую в таблице threads в отдельной колонке. При добавлении поста к треду обновляешь список последних постов.

Лучше наверно реляционно если это учебная задача.

>>434203

По идее должен. Но тут еще важно, слушает ли Апач на внешнем интерфейсе или нет. Там есть такая опция в httpd.conf, Listen: http://httpd.apache.org/docs/2.4/mod/mpm_common.html#listen

В ней ты можешь указать на каком интерфейсе принимать соединения. Если ты укажешь 127.0.0.1 то он будет слушать на внутреннем интерфейсе и снаружи будет не подключиться. Если укажешь IP сетевой карты то только на ней (это на случай если у тебя их несколько). А если указать 0.0.0.0 или не указывать котнкретный адрес, то на всех доступных.

То есть по умолчанию должно работать.
#400 #435533
>>434468

>>после прохождения этого мини-учебника какую литературу почитать?


> Бамп вопросу.


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

>>434671

Значит папки или файла нету какого-то. Есои проблема еще не решилась, напиши какой адрес пытаешься открыть, что в httpd.conf, есть ли на диске файл который пытаешь открыть.

>>434664

На PHP примерно та же зарплата (хоят конечно зависит от уровня, может и меньше чем на Яве) и тоже можно говорить с заказчиками по английски. А можно работать в компании со своим продуктом.

>>434718

Молодец, все правильно решено.
#401 #435540
>>434723

Теперь верно

>>434718

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

> foreach ($text as $key => $letter){


Неверно называны переменные.Должно быть не letter (буква) а sentence (предложение). лун не нужен

> $text[$key] = trim($text[$key]);


Вместо того чтобы копипастить text[$key] пиши так

$sentence = trim($sentence);

А в конце цикла ты можешь записать измененное предложение назад в массив.

> $text[$key] = preg_split('//u', $text[$key], -1, PREG_SPLIT_NO_EMPTY);


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

Аналогично тут:

> foreach ($result as $key => $word){


переменная word названа неправильно

> $result[$key]


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

> $result = preg_replace($reg, "$1 ", $result);


Можно просто когда ты делаешь implode добавить к точке пробел и этот кусок не понадобится.
#401 #435540
>>434723

Теперь верно

>>434718

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

> foreach ($text as $key => $letter){


Неверно называны переменные.Должно быть не letter (буква) а sentence (предложение). лун не нужен

> $text[$key] = trim($text[$key]);


Вместо того чтобы копипастить text[$key] пиши так

$sentence = trim($sentence);

А в конце цикла ты можешь записать измененное предложение назад в массив.

> $text[$key] = preg_split('//u', $text[$key], -1, PREG_SPLIT_NO_EMPTY);


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

Аналогично тут:

> foreach ($result as $key => $word){


переменная word названа неправильно

> $result[$key]


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

> $result = preg_replace($reg, "$1 ", $result);


Можно просто когда ты делаешь implode добавить к точке пробел и этот кусок не понадобится.
#402 #435544
>>434749

В Оп посте есть 2 книги по php. Насчет HTML/CSS, не знаю, что именно посоветовать.

С книгами есть 2 проблемы:

- они устаревают и часто пока книгу переведут, ей уже года 3-4 исполнится
- книги по PHP/HTML часто пишут малограмотные авторы которые делают кучу ошибок. Пример — Никсон или книга Heads First PHP, там очень неграмотный код.

Но это что каается PHP, а что каается HTML, бери любую книгу поновее и прверь что там не ставят слеш в конце одиночных тегов, то есть пишут не

<img /><br />

А

<img><br>

И в начале стоит <!DOCTYPE html>

если ставят слеш — значит это старье, еще из эпохи когда везде пытались использовать XHTML (что характрено, зачастую с ошибками).
#403 #435552
>>434780

Считает верно, только эти строки

> \t$sum = 39999;


> $payment = 5000;



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

>>435035

Я тут мимо проходил и напишу замечание:

> elseif(preg_match($from1to900, $number)){


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

>>435072

Математическими операциями вроде больше-меньше.

>>435075

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

>>435079

Мимосоветы:

- не смешивай в кучу php и html, не выводи html код через echo, используй шаблоны: http://www.phpinfo.su/articles/practice/shablony_v_php.html (заодно так проще натягивать и править верстку, когда html в отдельном файле а не набит кусками внутри php)
- ты никак не проверяешь при работе с БД что произошла ошибка. соединение могло не сработать, запрос мог не выполниться. После каждой mysqli команды должна стоять проверка результата.

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

- ты копипастишь параметры соединения:

> $db = array('host' => 'localhost', 'user' => 'root', 'pass' => '', 'name' => 'microboard');



Копипаста — зло.Надо вынести параметры в отдельный файл (обычно его называют config.php).

- вместо унылого цикла с for ($i=0; $i<$headersNumber; $i++) можно просто использовать mysqli_fetch_all

> echo "<p><b>№$row[0] $row[2] $row[3]


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

- у тебя SQL injection (погугли что это), то есть уязвимость позволяющая злодею выполнить произвольный SQL запрос. Потому что надо не вставлять переменные прямо в запрос:

> mysqli_query($link, "INSERT INTO `microboard`.`posts` (`name`, `message`) VALUES ('$username', '$text')");



А использовать плейсхолдеры:

http://php.net/manual/ru/mysqli.quickstart.prepared-statements.php
http://habrahabr.ru/post/141127/

(кстати в PDO это чуть короче пишется)

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

- у тебя XSS уязвимость, то есть пользователь может вывести любой html код включая скрипт на страницу. Почитай урок: https://gist.github.com/anonymous/52adda0113428b274c64

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

> !empty($_POST['username']) ? $username = $_POST['username'] : $username = "Аноним";


Не пиши так. Тут нужен if, не надо запутывать код.

- не верстай с помощью br, исплользуй CSS. Кстати у нас етсть хорошие задачки на HTML/CSS (в оп посте)

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

как видишь, ты сделал кучу ошибок в таком простом сайте. Если хочешь их исправить, я могу помочь советами, ответить на вопросы и проверить код.
#403 #435552
>>434780

Считает верно, только эти строки

> \t$sum = 39999;


> $payment = 5000;



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

>>435035

Я тут мимо проходил и напишу замечание:

> elseif(preg_match($from1to900, $number)){


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

>>435072

Математическими операциями вроде больше-меньше.

>>435075

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

>>435079

Мимосоветы:

- не смешивай в кучу php и html, не выводи html код через echo, используй шаблоны: http://www.phpinfo.su/articles/practice/shablony_v_php.html (заодно так проще натягивать и править верстку, когда html в отдельном файле а не набит кусками внутри php)
- ты никак не проверяешь при работе с БД что произошла ошибка. соединение могло не сработать, запрос мог не выполниться. После каждой mysqli команды должна стоять проверка результата.

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

- ты копипастишь параметры соединения:

> $db = array('host' => 'localhost', 'user' => 'root', 'pass' => '', 'name' => 'microboard');



Копипаста — зло.Надо вынести параметры в отдельный файл (обычно его называют config.php).

- вместо унылого цикла с for ($i=0; $i<$headersNumber; $i++) можно просто использовать mysqli_fetch_all

> echo "<p><b>№$row[0] $row[2] $row[3]


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

- у тебя SQL injection (погугли что это), то есть уязвимость позволяющая злодею выполнить произвольный SQL запрос. Потому что надо не вставлять переменные прямо в запрос:

> mysqli_query($link, "INSERT INTO `microboard`.`posts` (`name`, `message`) VALUES ('$username', '$text')");



А использовать плейсхолдеры:

http://php.net/manual/ru/mysqli.quickstart.prepared-statements.php
http://habrahabr.ru/post/141127/

(кстати в PDO это чуть короче пишется)

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

- у тебя XSS уязвимость, то есть пользователь может вывести любой html код включая скрипт на страницу. Почитай урок: https://gist.github.com/anonymous/52adda0113428b274c64

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

> !empty($_POST['username']) ? $username = $_POST['username'] : $username = "Аноним";


Не пиши так. Тут нужен if, не надо запутывать код.

- не верстай с помощью br, исплользуй CSS. Кстати у нас етсть хорошие задачки на HTML/CSS (в оп посте)

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

как видишь, ты сделал кучу ошибок в таком простом сайте. Если хочешь их исправить, я могу помочь советами, ответить на вопросы и проверить код.
#404 #435556
>>435128

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

Смотри, у тебя в последний месяц анон платит 5000, и сразу же выплачивает 4139 остатка. А ведь он не может сразу это выплатить, он должен подождать месяц, за который набегут проценты и комиссии и итоговая сумма выйдет больше — не 49139, а около 61270.

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

Надо смотреть чему равен остаток долга и обрабатывать ситуацию, когда она маленький, а не выплачивать сразу же 5000 вот в этом месте: ... + $servicePayment - $monthlyPayment;

Попробуй переписать код внутри цикла примерно так:

- прибавляем проценты и комиссию к остатку долга
- если остаток маленький, выплачиваем сколько осталось и уходим
- иначе платим 5000
#405 #435560
>>435131

Все правильно считает, молодец.

>>435138

> header("Content...


> ?>


> <?php



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

> return $result = array(


> ....


Не совмещай в одной строке присваивание ($x = 1) и return, это 2 команды и надо делать в 2 отдельных строках. А в данном случае переменная вообще не нужна и надо писать сразу return array( ....);

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

Ну сам подумай, функция makeOneStep ищет оптимальный путь от промежуточной (не начальной) до конечной точки. Соответственно, ей нужно знать промежуточную точку и конечную. Зачем ей передавать lowerTime? Или есть какая-то причина?

Также, нелогично в случае если путь не найден возвращать пустой массив. Логичнее null наверно.
#406 #435562
>>435229

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

>>435232

Не занимайся PHP, тогда проблемы не будет.

>>435236

О, почти все сделано. Только вот тут бросается в глаза:

> https://github.com/MindiMakridi/Students/blob/master/index.php#L105


> $searchLink = htmlspecialchars(urlencode($currentPage)) . "?order=" . ...


Длинные строки надо переносить, чтобы на том же гитхабе они не уехжали заправый край. Также, вместо того чтобы 4 раза писать htmlspecialchars проще применить его один раз ко всей ссылке (только amp; надо будет заменить на просто & в этом случае)

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

> https://github.com/MindiMakridi/Students/blob/master/profile.php#L72


> $token = createXsrfCookie( );


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

> https://github.com/MindiMakridi/Students/blob/master/lib/functions.php#L58


> ?>


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

Больше замечаний нет.

Ну и ты можешь не ждать меня, а потихоньку делать вторую задачу, на файлообменник с twig.
#406 #435562
>>435229

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

>>435232

Не занимайся PHP, тогда проблемы не будет.

>>435236

О, почти все сделано. Только вот тут бросается в глаза:

> https://github.com/MindiMakridi/Students/blob/master/index.php#L105


> $searchLink = htmlspecialchars(urlencode($currentPage)) . "?order=" . ...


Длинные строки надо переносить, чтобы на том же гитхабе они не уехжали заправый край. Также, вместо того чтобы 4 раза писать htmlspecialchars проще применить его один раз ко всей ссылке (только amp; надо будет заменить на просто & в этом случае)

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

> https://github.com/MindiMakridi/Students/blob/master/profile.php#L72


> $token = createXsrfCookie( );


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

> https://github.com/MindiMakridi/Students/blob/master/lib/functions.php#L58


> ?>


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

Больше замечаний нет.

Ну и ты можешь не ждать меня, а потихоньку делать вторую задачу, на файлообменник с twig.
#407 #435564
>>435562

>Не занимайся PHP, тогда проблемы не будет.


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

>а потихоньку делать вторую задачу, на файлообменник с twig


Файлообменник, я так понял, можно уже использовать как портфолио, но с моей версткой будет стыдно такое показывать кому-либо. Хочу стать гуру разметки, ну или хотя бы, чтобы странички были приятны глазу.
#408 #435565
>>435248

> А вопросы с подвохом? Это ведь шуточки про hr, да?


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

> Это вот всё на стажера нужно?


Не факт, что нужно

> В резюме про что писать-то?


Погугли «как составить резюме». Надо писать образование и какие технологии на каком уровне ты знаешь.

>>435253

Потому что тут они приводятся не к bool а к int. 0 -> 0, 'x' -> 0

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

>>435259

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

>>435262

Вот в этой строчке

> $creditBalance = ( $creditBalance * $percent ) + $servicePayment - $monthlyPayment;



Ты вычитытаешь monthlyPayment не глядя чему равен долг. А ведь может быть он меньше чем monthlypayment.

> $creditBalance == $monthlyPayment;


тут опечатка. == обозначает сравнение и используется внутри if, а ты наверно хотел написать просто =
#408 #435565
>>435248

> А вопросы с подвохом? Это ведь шуточки про hr, да?


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

> Это вот всё на стажера нужно?


Не факт, что нужно

> В резюме про что писать-то?


Погугли «как составить резюме». Надо писать образование и какие технологии на каком уровне ты знаешь.

>>435253

Потому что тут они приводятся не к bool а к int. 0 -> 0, 'x' -> 0

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

>>435259

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

>>435262

Вот в этой строчке

> $creditBalance = ( $creditBalance * $percent ) + $servicePayment - $monthlyPayment;



Ты вычитытаешь monthlyPayment не глядя чему равен долг. А ведь может быть он меньше чем monthlypayment.

> $creditBalance == $monthlyPayment;


тут опечатка. == обозначает сравнение и используется внутри if, а ты наверно хотел написать просто =
#409 #435566
>>435564
Нет проблем, используй дефолтные компоненты из bootstrap. Они сами по себе довольно приятны глазу.
#410 #435567
>>435565

>Потому что тут они приводятся не к bool а к int. 0 -> 0, 'x' -> 0


>


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



По мне дак, за такой не очевидный код бить нужно. Или в реальном мире это знание всё таки может пригодится?
#411 #435568
>>435567
Это ты еще Жаваскрипт не видел.
#412 #435569
>>435269

Кстати, верно.

>>435299

Ты бы скопипастил текст вопроса, а то там регистрация же нужна.

Там в объяснении пишут что дложно быть условие type = 'laptop' а у тебя его нет, может в этом дело?

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

>>435358

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

Смотри, у тебя условие продолжения записано как

> $firstInputMoney!=1000000


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

Также, это

> \t$firstInputMoney=$firstInputMoney+(($firstInputMoney/100)*10);



Надо упростить. Чтобы увеличить сумму на 10% достаточно просто умножить ее на 1.10 (вспоминай школьную математику).

И давай нормальные навазния переменным. Не $b, а $years например.

>>435413

Надо после каждой операции с mysqli делать проверку резудльтата через if, так как может произойти ошибка.

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

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

Если ты запускаешь код не на хостинге, а у себя то включи display_errors чтобы они выводились на экран. На хостинге включать не надо, смотри логи.
#412 #435569
>>435269

Кстати, верно.

>>435299

Ты бы скопипастил текст вопроса, а то там регистрация же нужна.

Там в объяснении пишут что дложно быть условие type = 'laptop' а у тебя его нет, может в этом дело?

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

>>435358

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

Смотри, у тебя условие продолжения записано как

> $firstInputMoney!=1000000


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

Также, это

> \t$firstInputMoney=$firstInputMoney+(($firstInputMoney/100)*10);



Надо упростить. Чтобы увеличить сумму на 10% достаточно просто умножить ее на 1.10 (вспоминай школьную математику).

И давай нормальные навазния переменным. Не $b, а $years например.

>>435413

Надо после каждой операции с mysqli делать проверку резудльтата через if, так как может произойти ошибка.

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

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

Если ты запускаешь код не на хостинге, а у себя то включи display_errors чтобы они выводились на экран. На хостинге включать не надо, смотри логи.
#413 #435571
>>435438

> там настроек куча, нужно в километровых текстовых файлах рыться


Не надо, те что по умолчанию годятся.

> и вообще я по-моему их много наустанавливал


Должна быть только одан MySQL и один Апач

> Warning: mysql_list_dbs() has been disabled for security reasons


Да, функция запрещена администратором, так как расширение mysql устарело несколько лет назад.

>>435446

Функция запрещена администратором так как устарела.

Не надо начинающим ставить денвер. Это сборка для опытных разработчиков. Надо ставить руками Апач/PHP/mysql. У нас есть мини-уроки на эту тему:

https://gist.github.com/codedokode/10774100
https://gist.github.com/codedokode/7054af4a03865c4cc863

Если ты не знаком с командной строкой вот урок:

https://gist.github.com/codedokode/10539568
#414 #435572
#415 #435573
>>435446

> Далее заходишь в phpmyadmin, который входит в обе сборки, создаешь там базу с таким же именем пустую, после чего жмешь импортировать


Полезнее начинабщему делать это руками в консоли mysql. Импортировать дамп можно командой

mysql -u{имяюзера} -p {имя базы данных} < {имя файла с дампом}

Например

mysql -uanon -p database1 < c:\tmp\dump.sql

> то попробуй скайп выключить


Лучше зайти в настройки скайпа и снять галочку «занимать порт 80»
#416 #435576
>>435438
>>435446

Ой, я ошибся. Функция запрещена не потому что устарела (хотя она на самом деле устарела) а потому что администратор ее отключил (кстати вывести список баз все равно можно запросом SHOW DATBASES).

И анон прав, нельзя совместно использовать mysql и mysqli функции.

>>435466

Стоит учить наверно.

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

>>435518

Удаленка, odesk

>>435519

Книга то слабая. Лучше год обучения в нашем треде, мы тебя гораздо лучше натренируем.

>>435520

Есть odesk тред в разделе /wrk

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

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

>>435564

А у нас есть задачи на HTML/CSS, хорошие, в конце надо сверстать сайт. Как всегдя, я буду строго придиратся к каждой ошибочке и неточности в решении. Посмотри: https://gist.github.com/codedokode/58ebc90bd006baf4b35c

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

Можно делать их параллельно с файлообменником, и вбрасывать сразу по несколько решений.
#416 #435576
>>435438
>>435446

Ой, я ошибся. Функция запрещена не потому что устарела (хотя она на самом деле устарела) а потому что администратор ее отключил (кстати вывести список баз все равно можно запросом SHOW DATBASES).

И анон прав, нельзя совместно использовать mysql и mysqli функции.

>>435466

Стоит учить наверно.

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

>>435518

Удаленка, odesk

>>435519

Книга то слабая. Лучше год обучения в нашем треде, мы тебя гораздо лучше натренируем.

>>435520

Есть odesk тред в разделе /wrk

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

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

>>435564

А у нас есть задачи на HTML/CSS, хорошие, в конце надо сверстать сайт. Как всегдя, я буду строго придиратся к каждой ошибочке и неточности в решении. Посмотри: https://gist.github.com/codedokode/58ebc90bd006baf4b35c

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

Можно делать их параллельно с файлообменником, и вбрасывать сразу по несколько решений.
#417 #435577
>>435446
у меня есть денвер, говорю же мскл на нем просто не работает.
>>435449
но этот хост поддерживает мскл. я создал там вручную менеджером БД и таблицу в ней. А вот что и где писать в таблицу и как выводить - хз.
#418 #435582
>>435577
базу данный MySQL то он без сомнения поддерживает, а вот библиотеку пхпшную mysql_... он не поддерживает наверное, поэтому тебе нужна mysqli_.. это тоже вещь для работы с базой данных MySQL, только новее, лол.
#419 #435584
>>435564

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

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

А верстка это лишь процесс переноса дизайна на язык HTML/CSS. Но верстальщику полезно понимать принципы оформления текста.

Про оформление текста могу посоветовать «Недизайнерская книга о дизайне». Она маленькая, но рассказывает основные принципы оформления текста.

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

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

Также, цитаты оформлены довольно бледным текстом, который плохо заметен на сером фоне.
#420 #435586
Аноны, вроде всем ответил, еси пропустил, напомните о себе.

>>435567

Не надо сравнивать строки с числами, это да.

>>435572

Не, неаккуратное какое-то решение. Ты сначала в минус уходишь, а потом пытаешься исправить это. Но почему бы просто не переделать код, чтобы вычитать столько сколько осталось, а не 5000?

Вот в этой строке

> \t$creditBalance = ( $creditBalance * $percent ) + $servicePayment - $monthlyPayment;



Ты вычитаешь всегда ровно 5000, даже если осталось немного. надо бы это исправить.
#421 #435587
>>435577

mysql и mysqli это разные расширения. Почему денвер не поддерживает, не знаю, но если это так то надо либо поставить расширение самому (либо включить его в php.ini) либо ставить Апач/PHP с нуля.

Сделай файл 1.php c кодом

<?php phpinfo( );

И открой его через браузер. Там выведется список включенных расширений, проверь что там есть mysqli. Если нет то там выводится путь к php.ini, попробуй в нем разрешить mysqli.
#422 #435593
Посоны, что означает часть кода - %{date_from}s %{date_to}s ?
#423 #435595
>>435586

>Не, неаккуратное какое-то решение.


Ты имеешь ввиду, что на одной строчке вычитается, а на другой сразу же прибавляется или что-то кардинально другой алгоритм? Если да, то признаю, проебал этот момент. А если нет, то хз, по мне так всё остальное уже будет шило на мыло.
#424 #435598
Какой же я тупой и бездарный. Я нихуя не понимаю в этом майсколе сраном. Я создал таблицу, в мануалах ее нужно текстом в пхп создавать, а там пхп админ - там все восем другое, я не понимаю, что это ячейки, что в них писать, вар инт куда там текст пихать !!! что это за таблицы блятб1!! попробую записать сообщения в другой пхп файл через fopen read write! в жопу мскл. неужели так трудно делать сраные сохраняемые комменты и регистрацию!
#425 #435599
>>435584
на сосаке длина строк тоже не ограничена.
#426 #435611
>>435595

> на одной строчке вычитается, а на другой сразу же прибавляется


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

>>435598

Спокойно, не нервничай, давай разберемся.

Ты явно не проходил курс для начинающих по mysql, так ведь? Сложно что-то понять если пропускать основы и сразу браться за сложное.

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

http://jtest.ru/bazyi-dannyix/sql-dlya-nachinayushhix-chast-3.html

(это третья часть, очевидно что перед ней надо пройти первые 2 части на которые там есть ссылки).

Также, дополнительно, чтобы закрепитть знания, советую решить 2-3 задачки на MySQL отсюда: https://gist.github.com/codedokode/10539213

Там же есть ссылка на учебник Пирамидина. Некоторые тут еще советую сайт sql-ex.ru но он требует регистрации.

Проходишь туториал под виндой, не работают русские буквы? Пиши SET NAMES cp866; в начале работы.

Первый раз в жизни видишь консоль и не понимаешь что это? Прочти инструкцию по командной строке https://gist.github.com/codedokode/10539568

Если что-то еще непонятно, задавай вопросы.
#427 #435612
>>435586
>>435595
Немного переделал, но хз, по мне так я не понял, что ты имеешь ввиду.
http://ideone.com/vMfEyo
#428 #435616
>>435598

А, перед прохождением туториала стоит почитать еще это: http://phpclub.ru/mysql/doc/tutorial.html

Про то как подсоединяться к серверу из командной строки. Да, начинабщему стоит начать с командной строки, а не phpmyadmin.
#429 #435618
>>435593

В каком контексте?

>>435599

На Хабре например ограничена.

>>435612

Теперь хорошо.
#430 #435619
>>435618

>Теперь хорошо.


Ачивмент анлокед: пхп-гуру.
#431 #435643
>>434651

>Насчет таблицы answer_attempts — тут конечно есть сложный вопрос, а что должно храниться в answer?


Я планирую просто текст.

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


Такой же план.

>С третьей стороны, а что если надо исправить опечатку в тесте или оказалось что правильный ответ был помечен неправильно?


Можно разрешить редактирование, но с обнулением всех результатов.

>А зачем вообще ты ввел куки? Для защиты от случайного перезапуска теста?


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

>Есть такое http://stackoverflow.com/a/22752533 — это для Yii 1 правда


Да, просто find()->where()->count() можно.

>>434652

>Явно надо это вынести в метод у модели (полуить N-й вопрос теста)


Да-да, унес.

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


В смысле, какую подгрузку? А про лишние SQL-запросы, там Yii сам же кеширует все, что кешируется.

>Подумай, не стоит ли это тоже сделать методов вроде такого:


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

https://github.com/sqghub/TestHub
Чуть-чуть подправил. Подумываю начать делать сами страницы.
#431 #435643
>>434651

>Насчет таблицы answer_attempts — тут конечно есть сложный вопрос, а что должно храниться в answer?


Я планирую просто текст.

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


Такой же план.

>С третьей стороны, а что если надо исправить опечатку в тесте или оказалось что правильный ответ был помечен неправильно?


Можно разрешить редактирование, но с обнулением всех результатов.

>А зачем вообще ты ввел куки? Для защиты от случайного перезапуска теста?


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

>Есть такое http://stackoverflow.com/a/22752533 — это для Yii 1 правда


Да, просто find()->where()->count() можно.

>>434652

>Явно надо это вынести в метод у модели (полуить N-й вопрос теста)


Да-да, унес.

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


В смысле, какую подгрузку? А про лишние SQL-запросы, там Yii сам же кеширует все, что кешируется.

>Подумай, не стоит ли это тоже сделать методов вроде такого:


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

https://github.com/sqghub/TestHub
Чуть-чуть подправил. Подумываю начать делать сами страницы.
#432 #435654
Ответ тут: http://ideone.com/ZlHzOS
#433 #435657
Еще у тебя тут вот сомнительное место

> https://github.com/sqghub/TestHub/blob/master/models/Question.php#L96


> \Yii::$app->getDb()->transaction(function () {


что это модель лезет куда-то в глобальные переменные? Из самого объекта AR никак нельзя получить ссылку на Db?
#434 #435659
>>435657
Ну я так понял $app действует как такой сервис-локатор. Хотя да, можно просто $this->getDb();
#435 #435661
>>435659

Сервис локатор это антипаттерн и плохая идея. Вот у меня был урок на эту тему: https://gist.github.com/codedokode/e1d31a31b37d5f635057

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

Конечно в Yii, я подозреваю, антипаттернов и так хоть отбавляй, но ты должен стараться не увеличивать их количество (если это не сложно; могут быть ситуации что по другому никак; либо смирись либо переходи на симфони 2).
#436 #435665
>>435661

>Хорошо когда объект получает зависимости через конструктор или сеттеры.


Он и получает. Просто если в конструкторе не указать бд, то он возьмет ту, что указана как db в сервис локаторе. Как-то так. В общем-то независимо от этого стоит брать бд из AR, а не из сервис локатора, я уже поменял.
#437 #435666
>>435659

Точнее не сам сервис локатор, а прямое обращение к нему. Вот так плохо:

$x = new X($serviceLocator); // надо передавать зависимости явно, чтобы было видно от каких классов зависит X

Так плохо:

function construct() {
$this->x = Locator::get('x'); // мы не можем подменить x на свой объект
}

Вот пример уместного использоваения servicelocator:

$a = $serviceLocator->getA( );
$b = $serviceLocator->getB( );
$x = new X($a, $b); // зависимости передаются явно, их можно поменить на что угодно

Обычно в таких случаях используют DI container, это класс который создает объекты по прописанным в коде или конфиге правилам:

// конфиг описывает что надо передать в конструктор для создания объекта
x:
class: 'X'
arguments: [@a, @b]

// использование
$x = $diContainer->get('x');

// Конструктор класса X
function construct(A $a, B $b) {
...
}

Так сделано например в Symfony 2:http://symfony.com/doc/current/book/service_container.html

Некоторые DI containers (в ZF2 например) пытаются сами угадать зависимости класса по тайп хинтам в конструкторе.
#437 #435666
>>435659

Точнее не сам сервис локатор, а прямое обращение к нему. Вот так плохо:

$x = new X($serviceLocator); // надо передавать зависимости явно, чтобы было видно от каких классов зависит X

Так плохо:

function construct() {
$this->x = Locator::get('x'); // мы не можем подменить x на свой объект
}

Вот пример уместного использоваения servicelocator:

$a = $serviceLocator->getA( );
$b = $serviceLocator->getB( );
$x = new X($a, $b); // зависимости передаются явно, их можно поменить на что угодно

Обычно в таких случаях используют DI container, это класс который создает объекты по прописанным в коде или конфиге правилам:

// конфиг описывает что надо передать в конструктор для создания объекта
x:
class: 'X'
arguments: [@a, @b]

// использование
$x = $diContainer->get('x');

// Конструктор класса X
function construct(A $a, B $b) {
...
}

Так сделано например в Symfony 2:http://symfony.com/doc/current/book/service_container.html

Некоторые DI containers (в ZF2 например) пытаются сами угадать зависимости класса по тайп хинтам в конструкторе.
#438 #435668
>>435560
Как условие звучит когда путь не найден? Проверить массив на пустоту?
#439 #435670
>>435668

Если ты возвращаешь null то можно просто написать

if ($newPath === null)

или, что короче, проверять что newPath пуст (а null это пустое значение):

if (!$newPath) {
...
}
#440 #435671
>>435666
Оу, там все иначе.
http://www.yiiframework.com/doc-2.0/yii-db-activerecord.html#getDb()-detail
Т.е. по умолчанию getDb() берет ту, что в сервис локаторе обозначена как db. А если мы хотим впихнуть другую, то мы переопределяем этот метод. Как-то глупо выходит, зависимость прямо в самом классе на уровне метода.
#441 #435674
>>435671

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

Да, это значит что ты не можешь создать объект и передать ему при создании какой-то экземпляр Db. Это делает код менее гибким. Видимо, это особо не требовалось (а для тестов они скорее всего подменяют глобальный объект db в service locator).

Аналогично сделано и в некоторых фреймворках на других языках, например ruby on rails, там тоже много статических вызовов.

Там в Yii много такого (в Yii 1 было хуже), это делается то ли ради упрощения (?) кода, то ли потому что не нужно, то ли потому что авторы немного велосипедисты. Точной причины я не знаю. Но большие фреймворки (ZF2, Symfony 2) используют DI и вообще новый код стараются писать в таком стиле, а цель нашего треда рассказать про то как принято делать.

Раз в Yii используется getDb, то используй ее.
#442 #435676
>>435671

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

get_instance()->doSomething

Похоже на Yii::app()

Причем что особо адово, там нет отдельного объекта $app, get_instance() возвращает первый созданный контроллер (то есть этот контроллер являлся одновременно объектом $app, если ни одного контроллера не создано то get_instance возвращает null). так что в сравнении с ним Yii сделал шаг вперед.
#443 #435698
ОП, оцени зародыш кода из задачки про преобразование цифр в буквы.
Что исправить, что добавить?
http://ideone.com/1pDtpZ
#444 #435707
>>435698

> if(preg_match($end5, $last2Digits)){


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

> $from1to900 = '#^[1-9][0?0?]$#';


То же самое

>if(preg_match('#^([0-9])|([0-9]){2}|([11-19])|([0-9]{3})$#', $number)){
То же самое

> $first = 0; $second = 0; $third = 0;


Не стоит экономит место в ущерб читабельности

> $first = floor($number/10)10;


> $first = floor($number / 100)100;


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

> ." тыс "


Надо писать «тысяча». А так же миллионы добавить.
11 Кб, 229x190
#445 #435820
Аноны, можете пояснить тупые общие вопросы по разработке? Вот, допустим заказывает какой-нибудь мужичок сайт у конторы веб-макак.
Во-первых. Как это происходит, если с нуля, - он дает уже готовый сервер с паролем-логином оплаченный, куда потом, после разработки, макаки сбрасывают плоды трудов своих(?) А если не с нуля?
Когда лепят сайт, допустим, магазин. Кто занимается наполнением со стороны клиента? Вебмастера или не всегда? Под это дело еще и "админку" делают, верно, для наполнения и управления? CMS? Сами макаки CMSки активно используют? Их нужно знать джуниору?
В чем пишет команда разработчиков? Большие IDE или могут и в простеньком редакторе? Их(ide) нужно знать? Насколько часто используются уже готовые шаблоны - свои/чужие? Как происходит разделение труда? Как делятся задания между работниками? Что по началу доверяют джуну?
#446 #435837
>>435707

> > ." тыс "


> Надо писать «тысяча». А так же миллионы добавить.


Я в конце планирую пройтись по результату, и в зависимости от цифры перед этим "тыс" добавить окончание.
#447 #435845
>>435820
Достаешь из штанов свой CMS, озалупливаешь БИТРИКС, водишь клиенту по губам, забираешь деньги.
#448 #435861
Вот так у меня первая задача на ксс получилась:
http://jsfiddle.net/0spo8sog/
#449 #435871
>>435560
>>435670
http://ideone.com/ubPwTW
Странно, у меня в изначальном коде была строчка if($newPath) но кажется либо я сам, либо кто-то указал что она там не нужна и убрал её.
#450 #435872
Вот я поделал задачки на нахождение пути (выше), сделал и на ООП и другие в учебнике ОПа, дальше хотел почитать о JScript'e но там завязка идет с CSS и HTML, так за что взяться далее? БД, CSS, HTML, JS или дальше PHP?
#451 #435874
Черт ногу сломит в этом CSS. Мне чудом повезло, что на главной странице htmlbook была статья про max-width, иначе я бы до вечера копался в справочнике css. Вот вторая задача:
http://jsfiddle.net/qvm4725q/1/
#452 #435896
>>435552
Спасибо большое за такую рецензию. Вот начал исправлять по мелочам, кроме верстки с помощью css, её пока не касался, но уже в планах скоро. Вот файлы: http://ideone.com/rPazRD

Столкнулся со след проблемой пока:
когда захотел сделать index.php + post.php в 1 файл, то вылезала следующая болячка, после того как ты запостил что-то на борду, и жал f5, браузер снова пытался отправить на неё данные, и соответственно появлялся новый пост, копирующий предыдущий. Я пришел к выводу, что у меня после того как я отправил сообщение, ничего не происходит с масивом $_POST[], и соответственно, так как идет проверка на него через isset в начале, то результат оказывается положительным и опять постится сообщение в базу из него.
unset($_POST) или unset($_POST['text']); не помогали. Поэтому пока оставил два файла, один (index.php) под получение данных из базы, и формирования массива для внешнего вида, и второй (post.php) для занесения сообщения в базу.

Следует ли все таки дела это в одном файле или можно два?

Так же вопрос по поводу htmlspecialchars, не совсем ясно как и что ей нужно фильтровать? Всю инфу которую вводит юзер в формы и может послаь всякими post \ get методами? Или что?

Можешь пока ответить на вот эти вопросы
29 Кб, 580x237
#453 #435934
Этот тред подходит для всех, или только для очень умных от природы, выпускников матфака, людей с ярко выраженным логическим мышлением?
#454 #435942
>>435934
Только для выпускников MIT, с как минимум двумя научными публикациями.
#455 #435946
>>435942
Поддвачну.
мимо-ректор-MIT
#456 #435947
Вот PHP функция, которая должна проверять заполненность полей:
function check1($a, $b) {
\tif ($a='' || $b=''){//rabotai ska
\t\techo "11111";}
\telse {rnd($_GET['a'], $_GET["b"]);}
}
check1($_GET['a'], $_GET["b"]);
Естественно, при тесте выводит ошибку о том что "для функции рнд нужны параметры".
Внимание вопрос: что не так и как это исправить? Инбифо: жабаскрипт.
#457 #435960
Какие там вообще щас расценки на фрилансе и какие типы работ?
Сколько например по времени будет сделать сайт и сколько это будет стоить?
Если я сейчас начну изучать с нуля и начну с 1 января 2016 фрилансить на одеске, то $200 смогу сразу получать за месяц?
#458 #435962
>>435947
Все, уже не надо.
#459 #435998
>>435820

>он дает уже готовый сервер с паролем-логином оплаченный, куда потом, после разработки, макаки сбрасывают плоды трудов своих(?)


Нет, обычно это тоже пилить контора

>А если не с нуля?


it depends

>Кто занимается наполнением со стороны клиента? Вебмастера или не всегда?


Не всегда

>Под это дело еще и "админку" делают, верно, для наполнения и управления?


Да, можно сделать кастомную

> CMS?


CMS

>Сами макаки CMSки активно используют?


Зависит от конторы
#460 #436002
>>435820

> Их нужно знать джуниору?


Вообще нет, но мало ли какие требования у конторы твоего залупинска

>В чем пишет команда разработчиков? Большие IDE или могут и в простеньком редакторе?


В чем удобно в том и пишет

> Их(ide) нужно знать?


Нет, освоишься по ходу дела

>Насколько часто используются уже готовые шаблоны - свои/чужие?


Постоянно, гугл лучший друг макаки

>Как происходит разделение труда?


В разных конторах по разному. В конторе твоего залупинска вероятно все пилят всё, максимум кто на верстке + скрипты, кто то на похапе+мускуль

>Как делятся задания между работниками?


Какая блять, разница?

>Что по началу доверяют джуну?


То что никто больше не хочет делать
#461 #436016
Сделал про вектор, как моржно улучшить?
http://ideone.com/fork/NgH7eg
#462 #436032
Когда описываешь методы в классе их нельзя прерывать HTML ?
#463 #436034
>>436032
А зачем такой изврат?
#464 #436048
Сделал часть задачи с числами. Пока только тысячи.
http://ideone.com/zt8sKk
#465 #436052
Помогите разобраться с кнопкой. Мне не нужна например кнопка вместе с формой, мне нужна скажем просто кнопка на страничке, которая будет посылать на сервер запрос, как это сделать? Скажем я тестирую свою гостевуху, и в ней накапливается всякая хрень, и вот я захотел в правом углу сделать кнопку, при нажатии на которую бы слался какой-то запрос на сервер. Как это сделать?
64 Кб, 1227x687
#466 #436056
Вроде правильно решил? Но так и не понял что можно было написать в коментариях.
#467 #436058
>>436056
Неправильно. Ты должен был получить количество используя две другие переменные. Понимаешь?
#468 #436059
>>436058
Понял, щас буду думать.
#469 #436060
>>436059
Ты присвоил переменным значения - используй теперь сами переменные для подсчетов.
36 Кб, 1105x351
#470 #436061
>>436058
Так чтоли? Так что же можно написать в коментариях? Типо просто "Число долларов умножаем на курс ОБМЕНА"?
#471 #436062
>>436061
Комментарии там для тебя ОП-написаны. Ты можешь ничего не писать пока сам и другие понимают что происходит в программе.
#472 #436063
>>436062
Это понимаю. Просто я имел в виду, что я правильно понял или можно было коментарий совсем по другом изложить?
#473 #436067
>>435820

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


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

> Кто занимается наполнением со стороны клиента?


Иногда заказчик, иногда веб-студия. Занимается этим так называемый «контент-менеджер» (как правило студенты какие-нибудь), но разумеется при нехватке людей это могут поручить и тебе как самому молодому.

> Под это дело еще и "админку" делают, верно, для наполнения и управления? CMS?


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

> Их нужно знать джуниору?


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

> В чем пишет команда разработчиков? Большие IDE или могут и в простеньком редакторе?


Кто как хочет, но в IDE удобнее

> Их(ide) нужно знать?


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

> Насколько часто используются уже готовые шаблоны - свои/чужие?


Часто

> Как делятся задания между работниками?


Старший программист распределеяет

> Что по началу доверяют джуну?


Баги, мелкие правки

Вообще, лучше бы ты беспокоился по поводу знания языка PHP, HTML, JS, ООП, фрейморков, а не думал о том кто арендует хостинг.
#473 #436067
>>435820

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


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

> Кто занимается наполнением со стороны клиента?


Иногда заказчик, иногда веб-студия. Занимается этим так называемый «контент-менеджер» (как правило студенты какие-нибудь), но разумеется при нехватке людей это могут поручить и тебе как самому молодому.

> Под это дело еще и "админку" делают, верно, для наполнения и управления? CMS?


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

> Их нужно знать джуниору?


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

> В чем пишет команда разработчиков? Большие IDE или могут и в простеньком редакторе?


Кто как хочет, но в IDE удобнее

> Их(ide) нужно знать?


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

> Насколько часто используются уже готовые шаблоны - свои/чужие?


Часто

> Как делятся задания между работниками?


Старший программист распределеяет

> Что по началу доверяют джуну?


Баги, мелкие правки

Вообще, лучше бы ты беспокоился по поводу знания языка PHP, HTML, JS, ООП, фрейморков, а не думал о том кто арендует хостинг.
#474 #436069
>>436067

>Вообще, лучше бы ты беспокоился по поводу знания языка PHP, HTML, JS, ООП, фрейморков, а не думал о том кто арендует хостинг.


И зачем половина этого, если сайты пилят на CMS?
#476 #436072
>>436070
У тебя имя переменной и \n слилось
#477 #436073
>>436070
Точка с запятой.
#478 #436074
>>436070
А все нашел, забыл просто ; в конце поставить.
Ну всё я спать, завтра с новыми силами опять начну после работы, а то пока пневмания и лечиться/спать надо.

Я так понял прийдется вспоминать математику с 5 по 11 классы, а это очень, очень хуёво, так как я плохо это помню.
#479 #436075
>>436072
Так тоже можно. У меня и так и так получалось, ну твой вариант конечно красивее, но мой компактнее.
#481 #436077
>>435837

> и в зависимости от цифры перед этим "тыс" добавить окончание.


Только без строковых функций и регулярок

>>435861

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

Также, у тебя есть ошибка:

> height: 10%


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

Ты можешь прочесть об этом в стандарте CSS2 (англ.): http://www.w3.org/TR/CSS2/visudet.html#the-height-property под заголовком <percentage>

Или тут на русском: http://learn.javascript.ru/height-percent

Потому ты можешь задать высоту только в пикселях.

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

>>435871

Ох, все рабоатет, но вот еще чуть-чуть надо код улучшить.

Строка 157,

> return $result = array(


Это ты не исправил. Перечитай замечание тут: >>435560\t

Строка 167,

> $xTime = $time;


> $xTime += $paths[$startPoint][$stationName]['time'];


Эти 2 строки можно (и нужно) объединить в одну.

> if (!isset($lowerTime)


Это очень плохо что переменная то есть, то нет. Как можно в таких условиях писать надежный код? Сделай чтобы переменная была всегда. Можешь ей в начале присвоить INF (бесконечность)
#481 #436077
>>435837

> и в зависимости от цифры перед этим "тыс" добавить окончание.


Только без строковых функций и регулярок

>>435861

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

Также, у тебя есть ошибка:

> height: 10%


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

Ты можешь прочесть об этом в стандарте CSS2 (англ.): http://www.w3.org/TR/CSS2/visudet.html#the-height-property под заголовком <percentage>

Или тут на русском: http://learn.javascript.ru/height-percent

Потому ты можешь задать высоту только в пикселях.

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

>>435871

Ох, все рабоатет, но вот еще чуть-чуть надо код улучшить.

Строка 157,

> return $result = array(


Это ты не исправил. Перечитай замечание тут: >>435560\t

Строка 167,

> $xTime = $time;


> $xTime += $paths[$startPoint][$stationName]['time'];


Эти 2 строки можно (и нужно) объединить в одну.

> if (!isset($lowerTime)


Это очень плохо что переменная то есть, то нет. Как можно в таких условиях писать надежный код? Сделай чтобы переменная была всегда. Можешь ей в начале присвоить INF (бесконечность)
#482 #436078
>>436077

>Это очень плохо что переменная то есть, то нет. Как можно в таких условиях писать надежный код? Сделай чтобы переменная была всегда. Можешь ей в начале присвоить INF (бесконечность)


Я думал об этом, но если в начале присваивать INF - разве тогда при рекурсии переменная не будет перезаписываться при каждом самовызове?
#483 #436079
>>436077

> Только без строковых функций и регулярок


А я уже все переделал.>>436048
#484 #436080
>>435872

> дальше хотел почитать о JScript'e но там завязка идет с CSS и HTML, так за что взяться далее? БД, CSS, HTML, JS или дальше PHP?


HTML/CSS конечно нужны. Ведь на этом языке верстаются странички которые ты видишь в своем браузере. Как ты будешь делать сайты без знания HTML?

Яваскрипт надо учить после HTML/CSS. Но если ты решаешь мои задачи, то первые задачи на JS не используют DOM (не взаимодействуют с версткой) и их по идее можно решать параллельно с изучением HTML. Но дальше он все равно понадобится.

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

Так что советую изучить основы HTML (у тебя уйдет пара дней, он простой),а потом начинай решать задачу по PHP и параллельно решай задачи HTML/CSS.

По ходу решения тебе понадобится SQL, опять же, у меня есть задачи на него и там же список туториалов: https://gist.github.com/codedokode/10539213

Опять же, основы SQL выучить это несколько дней, а подробно можно изучить позже.
#486 #436089
>>435874

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

Тут у тебя ошибочка: если растянуть окно то блок шириной 600px должен быть по центру. А у тебя он смещен влево.

Также, добавь поля (padding) и рамку (border). А то у тебя сверху и снизу текст упирается в край блока.

Ну и я думаю, для такой простой задачи использовать 2 элемента (div и p) — перебор. Оставь только один.

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

- width, height, min/max-width/height
- padding, padding-left/top etc.
- margin, margin-left/top etc.
- border, border-width, border-style, border-color
- font, font-size, font-weight, font-style, line-height
- color, background-color

Прочитай про эти свойства и прочти про боксовую модель если еще не читал: http://softwaremaniacs.org/blog/2005/07/08/css-boxes/ (часть про IE5/6 устарела, не читай ее).

Для решения 3 задачи тебе надо будет прочесть про сущности (html entitites): http://htmlbook.ru/samhtml/tekst/spetssimvoly

Для 4-й: надо изучить свойство display, а также vertical-align (обрати внимание: оно работает только в 2 ситуациях, а именно выравнивает строчные боксы внутри строки и выравнивает содержимое ячейки таблицы).

Есть такой цикл статей: http://css-live.ru/css/vvedenie-v-inlajnovyj-kontekst-formatirovaniya-ikf-osnovnye-ponyatiya-1-ya-publikaciya-cikla-tajny-css2-1.html но он очень сложный и наверно не стоит его пока читать (не бойся, это знать особо не требуется).

Для 5-й: изучи как padding/margin/width/height работает на строчных боксах.

http://css-live.ru/css/vvedenie-v-inlajnovyj-kontekst-formatirovaniya-ikf-osnovnye-ponyatiya-2-ya-publikaciya-cikla-tajny-css2-1.html

Для 6-й придется изучить float и clear:

http://softwaremaniacs.org/blog/2005/12/01/css-layout-float/
http://softwaremaniacs.org/blog/2005/09/05/css-layout-flow-margins/

Ну и если этого недостаточно, напиши, я еще подсказку дам.
#486 #436089
>>435874

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

Тут у тебя ошибочка: если растянуть окно то блок шириной 600px должен быть по центру. А у тебя он смещен влево.

Также, добавь поля (padding) и рамку (border). А то у тебя сверху и снизу текст упирается в край блока.

Ну и я думаю, для такой простой задачи использовать 2 элемента (div и p) — перебор. Оставь только один.

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

- width, height, min/max-width/height
- padding, padding-left/top etc.
- margin, margin-left/top etc.
- border, border-width, border-style, border-color
- font, font-size, font-weight, font-style, line-height
- color, background-color

Прочитай про эти свойства и прочти про боксовую модель если еще не читал: http://softwaremaniacs.org/blog/2005/07/08/css-boxes/ (часть про IE5/6 устарела, не читай ее).

Для решения 3 задачи тебе надо будет прочесть про сущности (html entitites): http://htmlbook.ru/samhtml/tekst/spetssimvoly

Для 4-й: надо изучить свойство display, а также vertical-align (обрати внимание: оно работает только в 2 ситуациях, а именно выравнивает строчные боксы внутри строки и выравнивает содержимое ячейки таблицы).

Есть такой цикл статей: http://css-live.ru/css/vvedenie-v-inlajnovyj-kontekst-formatirovaniya-ikf-osnovnye-ponyatiya-1-ya-publikaciya-cikla-tajny-css2-1.html но он очень сложный и наверно не стоит его пока читать (не бойся, это знать особо не требуется).

Для 5-й: изучи как padding/margin/width/height работает на строчных боксах.

http://css-live.ru/css/vvedenie-v-inlajnovyj-kontekst-formatirovaniya-ikf-osnovnye-ponyatiya-2-ya-publikaciya-cikla-tajny-css2-1.html

Для 6-й придется изучить float и clear:

http://softwaremaniacs.org/blog/2005/12/01/css-layout-float/
http://softwaremaniacs.org/blog/2005/09/05/css-layout-flow-margins/

Ну и если этого недостаточно, напиши, я еще подсказку дам.
#487 #436090
>>435874

Еще ошибки:

> bottom:1px;


bottom работает только совместно с позиционированием (position), тут оно бесполезно

> font-size: 14px;


Если задаешь font-size всегда рядом задавай line-height иначе она унаследуется от родителя.
21 Кб, 468x480
#488 #436092
Вебаны, как вы учили JS? Есть какие-нибудь годные видеогайды?
#489 #436094
>>436016

Слушай, можешь пояснить по поводу этого куска кода:

function addWorker(Employee $employee)

{
$this->workers[] = $employee;
}

Я немного не понял что выступает в качестве аргумента функции и в этом случае в массив $this->workers[] добавится уже посчитанные значения по кофе, зарплатам и страницам?
#490 #436122
ОПчик, подскажи, в чем проблема? Почему он ноль в начало пихает?
http://ideone.com/5uNo22
#491 #436126
>>435896

Файлы, если несколько, удобнее заливать на github, а если ты пока не освоил git (что плохо), то на gist.github.com — там можно добавлять файлы перетаскиванием.

Вот замечания по тому, что получилось:

Ты не исправил это: что когда ты вызываешь функции работы с mysqli, надо проверять результат который они возвращают. Ну например, возьмем mysqli_query и прочтем мануал по ней: http://php.net/manual/ru/mysqli.query.php

> Возвращаемые значения


> Возвращает FALSE в случае неудачи



Значит мы должны после вызова с помощью if проверить не получили ли мы false, и если получили то завершать скрипт с ошибкой (так как запрос выполнить не удалось).

Ну и я советовал бы освоить ООП-версию mysqli либо PDO ибо этот подход с вызовом функций никто сейчас не использует.

> \t$posts[] = mysqli_fetch_assoc($queryResult);


Есть же mysqli fetch all которая выбирает сразу все записи в массив, и цикл можно убрать.

> mysqli_query($link, "INSERT INTO `microboard`.`posts` (`name`, `message`) VALUES ('$username', '$text')");


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

htmlspecilachars надо использовать не тут, а при выводе в шаблоне.

Никогда не используй echo а шаблоне, так как html код внутри кавычек писать и читать неудобно. Используй тег <?= ... ?>

В шаблоне используй версии операторов с двоеточием вместо фигурных скобок ради читабельности. Посмотри пример кода тут: http://www.phpinfo.su/articles/practice/shablony_v_php.html в конце статьи.

> \tfor($i=0; $i<$headersNumber; $i++) {


Для перебора массива короче и читабельнее использовать foreach

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


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

Редирект делается через header(location:...)

> Я пришел к выводу, что у меня после того как я отправил сообщение, ничего не происходит с масивом $_POST[], и соответственно, так как идет проверка на него через isset в начале, то результат оказывается положительным и опять постится сообщение в базу из него.


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

После редиректа не забудь сделать die ()

> Следует ли все таки дела это в одном файле или можно два?


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

> Так же вопрос по поводу htmlspecialchars, не совсем ясно как и что ей нужно фильтровать?


Используй htmlspecialchars в шаблоне при выводе любых данных. Она превращает (ты читал мануал? прочитай) символы вроде < в спецсимволы и если злоумышленник передаст html-теги то после экранированяи они превратятся в обычный текст и XSS не произойдет. Ну и перечитай мой урок про XSS если не читал.

То есть надо выводить переменные через

<?= htmlspecialchars($x, ENT_QUOTES ?>

и ты будешь защищен от XSS.
#491 #436126
>>435896

Файлы, если несколько, удобнее заливать на github, а если ты пока не освоил git (что плохо), то на gist.github.com — там можно добавлять файлы перетаскиванием.

Вот замечания по тому, что получилось:

Ты не исправил это: что когда ты вызываешь функции работы с mysqli, надо проверять результат который они возвращают. Ну например, возьмем mysqli_query и прочтем мануал по ней: http://php.net/manual/ru/mysqli.query.php

> Возвращаемые значения


> Возвращает FALSE в случае неудачи



Значит мы должны после вызова с помощью if проверить не получили ли мы false, и если получили то завершать скрипт с ошибкой (так как запрос выполнить не удалось).

Ну и я советовал бы освоить ООП-версию mysqli либо PDO ибо этот подход с вызовом функций никто сейчас не использует.

> \t$posts[] = mysqli_fetch_assoc($queryResult);


Есть же mysqli fetch all которая выбирает сразу все записи в массив, и цикл можно убрать.

> mysqli_query($link, "INSERT INTO `microboard`.`posts` (`name`, `message`) VALUES ('$username', '$text')");


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

htmlspecilachars надо использовать не тут, а при выводе в шаблоне.

Никогда не используй echo а шаблоне, так как html код внутри кавычек писать и читать неудобно. Используй тег <?= ... ?>

В шаблоне используй версии операторов с двоеточием вместо фигурных скобок ради читабельности. Посмотри пример кода тут: http://www.phpinfo.su/articles/practice/shablony_v_php.html в конце статьи.

> \tfor($i=0; $i<$headersNumber; $i++) {


Для перебора массива короче и читабельнее использовать foreach

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


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

Редирект делается через header(location:...)

> Я пришел к выводу, что у меня после того как я отправил сообщение, ничего не происходит с масивом $_POST[], и соответственно, так как идет проверка на него через isset в начале, то результат оказывается положительным и опять постится сообщение в базу из него.


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

После редиректа не забудь сделать die ()

> Следует ли все таки дела это в одном файле или можно два?


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

> Так же вопрос по поводу htmlspecialchars, не совсем ясно как и что ей нужно фильтровать?


Используй htmlspecialchars в шаблоне при выводе любых данных. Она превращает (ты читал мануал? прочитай) символы вроде < в спецсимволы и если злоумышленник передаст html-теги то после экранированяи они превратятся в обычный текст и XSS не произойдет. Ну и перечитай мой урок про XSS если не читал.

То есть надо выводить переменные через

<?= htmlspecialchars($x, ENT_QUOTES ?>

и ты будешь защищен от XSS.
#492 #436129
>>436069
Ну если ты собрался всю жизнь сидеть в студии своего зажопинска и пилить визитки для местых ооо вектор, то незачем.
#493 #436130
>>436122

>На вашем счету ноль один миллион сто девяносто пять тысяч девятьсот двадцать пять (1195925) рублей


Вот из-за чего?
#494 #436131
>>436092
Посмотри канал Sorax на ютубе, но он на любителя
#495 #436133
>>436129
Нет ну я серьезно спрашиваю. Вы говорите, что все пилят на CMS, а затем вы же наезжаете на мой зажопинск.
#496 #436135
>>435896

Давай я тебя научу как проверить любую форму (в том числе твою гостевуху) на XSS. Введи туда текст вроде такого:

<b>hello

то есть HTML тег + текст, отправь форму и проверь, что выведется. Если текст на странице стал жирным (то есть <b> вставился как HTML тег а не как текст) то сайт уязвим (часто самописные сайты уязвимы, а вот сайты на CMS как правило защищены). Затем, попробуй второй вариант:

">'>&copy;<b>hello

Этот текст тоже должен вывестись как есть. Если он вывелся, то все ок. Если нет (например &copy; превратился в © или часть символов потерялась) — на сайте XSS.

Делай такие проверки только на своих сайтах или с разрешения владельца сайта. ну или хотя бы позаботься об анонимности[/spolier]

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

Для проверки на SQL инъекцию можно вводить (только на своем сайте или с разрешения владельца) такие строчки:

' OR 1=1 # (это может сработать в неправильно написанной форме логина)
" OR 1=1 #

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

Вики: https://ru.wikipedia.org/wiki/%D0%92%D0%BD%D0%B5%D0%B4%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_SQL-%D0%BA%D0%BE%D0%B4%D0%B0
Школофорум: http://forum.antichat.ru/thread43966.html

# это символ комментария, используемый чтобы закомментировать остаток запроса

Во многих случаях одна SQL инъекция позволяет вытянуть всю важную информацию из базы, а зачастую и из файлов на диске и взломать сайт.
#496 #436135
>>435896

Давай я тебя научу как проверить любую форму (в том числе твою гостевуху) на XSS. Введи туда текст вроде такого:

<b>hello

то есть HTML тег + текст, отправь форму и проверь, что выведется. Если текст на странице стал жирным (то есть <b> вставился как HTML тег а не как текст) то сайт уязвим (часто самописные сайты уязвимы, а вот сайты на CMS как правило защищены). Затем, попробуй второй вариант:

">'>&copy;<b>hello

Этот текст тоже должен вывестись как есть. Если он вывелся, то все ок. Если нет (например &copy; превратился в © или часть символов потерялась) — на сайте XSS.

Делай такие проверки только на своих сайтах или с разрешения владельца сайта. ну или хотя бы позаботься об анонимности[/spolier]

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

Для проверки на SQL инъекцию можно вводить (только на своем сайте или с разрешения владельца) такие строчки:

' OR 1=1 # (это может сработать в неправильно написанной форме логина)
" OR 1=1 #

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

Вики: https://ru.wikipedia.org/wiki/%D0%92%D0%BD%D0%B5%D0%B4%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_SQL-%D0%BA%D0%BE%D0%B4%D0%B0
Школофорум: http://forum.antichat.ru/thread43966.html

# это символ комментария, используемый чтобы закомментировать остаток запроса

Во многих случаях одна SQL инъекция позволяет вытянуть всю важную информацию из базы, а зачастую и из файлов на диске и взломать сайт.
156 Кб, 787x830
#497 #436141
>>435934

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

>>435947

>>435960

Открой fl.ru, odesk, freelance (без минуса) и сделай исследование. Надеюсь, учить пользоваться поиском на сайте тебя не надо.

> Сколько например по времени будет сделать сайт и сколько это будет стоить?


Смотря какой. Обычно стоимость определяется как число_часов × стоимость_часа + надбавка, а сделать сайт может занять от нескольких часов (используя стандартную CMS) до месяцев и лет.

> Если я сейчас начну изучать с нуля и начну с 1 января 2016 фрилансить на одеске, то $200 смогу сразу получать за месяц?


Все зависит от тебя. Даже при ставке $6 в час (полный ноль) 200 долларов это всего лишь 33 часа работы.

Алсо, в /wrk есть odesk тред. Изучи его.

Используй Гугл, введя туда «сайт_про_IT odesk» (плохо если ты не догадался это сделать):

http://www.google.ru/search?sourceid=chrome&ie=UTF-8&q=habr+odesk
http://www.google.ru/search?sourceid=chrome&ie=UTF-8&q=dou.ua+odesk
http://www.google.ru/search?sourceid=chrome&ie=UTF-8&q=dev.by+odesk
#498 #436142
>>435960

На одеске расценки от $1 в час (индия, пакистан, иогда в заказах прямо пишут: не просите больше 2 долларов) до 40-50 (есть наверно и больше но я не знаю как они уговаривают заказчиков столько заплатить).

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

>>435820

Разделение труда в больших богатых конторах. В маленькой студии лучше уметь все (но уровень умений там соответствующий).

>>436016

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

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

> if ($this->chief) {


> $this->pages = 0;


Это нехорошо как-то, незачем менять свойство класса, лучше просто сделать return 0, а то в твоем варианте при разжаловании из дложности начальника pages не восстановится.

> $count = count($this->workers);


> return $count;


А что сразу не написать не return count(..)?

> return round($sum, 1);


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

> function totalCoffee()


Имя функции должно начинаться с глагола, сделайЧтоТо, напрмер getToatlCoffee или getTotalCoffeeConsumption().

> $string = preg_split('//u', $string, -1, PREG_SPLIT_NO_EMPTY);


> while (count($string) <= $lenght) {


Чтобы добавить несколько пробелов сразу, есть str_repeat, чтобы найти длину строки есть mb_strlen, а ты как-то переусложнил все.

> for ($i = 0; $i <= count($departments) - 1; $i++) {


> ... $departments[$i]..


используй тут foreach $departments as $department

> foreach ($departments as $value) {


Почитай статью: http://learn.javascript.ru/write-unmain-code#будьте-абстрактны-при-выборе-имени

Не исплоьзуй бессмысленные имена вроде value, tmp, data и так далее.

Ну а вообще неплохо, я вижу, ты ООП более-менее понимаешь.
#498 #436142
>>435960

На одеске расценки от $1 в час (индия, пакистан, иогда в заказах прямо пишут: не просите больше 2 долларов) до 40-50 (есть наверно и больше но я не знаю как они уговаривают заказчиков столько заплатить).

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

>>435820

Разделение труда в больших богатых конторах. В маленькой студии лучше уметь все (но уровень умений там соответствующий).

>>436016

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

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

> if ($this->chief) {


> $this->pages = 0;


Это нехорошо как-то, незачем менять свойство класса, лучше просто сделать return 0, а то в твоем варианте при разжаловании из дложности начальника pages не восстановится.

> $count = count($this->workers);


> return $count;


А что сразу не написать не return count(..)?

> return round($sum, 1);


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

> function totalCoffee()


Имя функции должно начинаться с глагола, сделайЧтоТо, напрмер getToatlCoffee или getTotalCoffeeConsumption().

> $string = preg_split('//u', $string, -1, PREG_SPLIT_NO_EMPTY);


> while (count($string) <= $lenght) {


Чтобы добавить несколько пробелов сразу, есть str_repeat, чтобы найти длину строки есть mb_strlen, а ты как-то переусложнил все.

> for ($i = 0; $i <= count($departments) - 1; $i++) {


> ... $departments[$i]..


используй тут foreach $departments as $department

> foreach ($departments as $value) {


Почитай статью: http://learn.javascript.ru/write-unmain-code#будьте-абстрактны-при-выборе-имени

Не исплоьзуй бессмысленные имена вроде value, tmp, data и так далее.

Ну а вообще неплохо, я вижу, ты ООП более-менее понимаешь.
#499 #436143
>>436052
А что конкретно у тебя не получается?
#500 #436144
>>435960
ууу, платина
#501 #436147
>>436032

Ни в коем случае. А зачем тебе это? Приведи пример кода?

>>436048

first/second лучше бы заменить на hundreds/tens/units. У тебя же в редакторе есть поиск/замена? Поучись заодно ей пользоваться, тут поменять имена дело на полторы минуты.

В функции smallNumberToText($number, $isFemale) очень сложный код. Упрости его, чтобы было примерно так:

слова = пусто;

если (в числе есть сотни) {
добавляем в слова сотни;
}

если (есть десятки) {
добаляем десятки;
}
...

> function Thousand($number){


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

Функции Thousand и Million очень похожи на inclineWord($number), согласись? То есть получается ты сделал 3 копии одной функции. Так, разумеется, не пойдет. Копипасты не должно быть.

> if(((((floor($number / 1000000)%10>= 5) && (floor($number / 1000000)%10 <= 9 || floor($number / 1000000)%100 >= 10 && floor($number / 1000000)%100 <= 19)||floor($number / 1000000) % 10 == 0)))){


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

> PHP Warning: Missing argument 2 for smallNumberToText(), called in /home/ICHKgN/prog.php on line 135 and defined in /home/ICHKgN/prog.php on line 29


аргумент забыл передать

> Пока только тысячи.


а я все равно все проверил
#501 #436147
>>436032

Ни в коем случае. А зачем тебе это? Приведи пример кода?

>>436048

first/second лучше бы заменить на hundreds/tens/units. У тебя же в редакторе есть поиск/замена? Поучись заодно ей пользоваться, тут поменять имена дело на полторы минуты.

В функции smallNumberToText($number, $isFemale) очень сложный код. Упрости его, чтобы было примерно так:

слова = пусто;

если (в числе есть сотни) {
добавляем в слова сотни;
}

если (есть десятки) {
добаляем десятки;
}
...

> function Thousand($number){


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

Функции Thousand и Million очень похожи на inclineWord($number), согласись? То есть получается ты сделал 3 копии одной функции. Так, разумеется, не пойдет. Копипасты не должно быть.

> if(((((floor($number / 1000000)%10>= 5) && (floor($number / 1000000)%10 <= 9 || floor($number / 1000000)%100 >= 10 && floor($number / 1000000)%100 <= 19)||floor($number / 1000000) % 10 == 0)))){


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

> PHP Warning: Missing argument 2 for smallNumberToText(), called in /home/ICHKgN/prog.php on line 135 and defined in /home/ICHKgN/prog.php on line 29


аргумент забыл передать

> Пока только тысячи.


а я все равно все проверил
#502 #436149
>>436052

Помести кнопку внутрь формы. Дополнительные данные можно передать через скрытый input type=hidden. Тогда при нажатии будет отправляться форма.

>>436056

Комментарий можно не писать. Но задачу ты решил не совсем правильно, так как если мы поменяем исходные данные (строчку $dollars = 200), результат не поменяется, а должен поменяться.

>>436061

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

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

>>436063

Можно вообще удалить комментарий.

>>436069

В некоторых случаях для CMS надо делать и натягивать верстку (нужен HTML/CSS, скорее всего JS), а иногда сделать какой-то свой модуль или подправить существующий (нужен PHP/SQL). Но делать примитивные однообразные кривые сайты тебе скоро надоест и захочется перебраться в компанию покрупнее и попрофейсиональнее, работющую на запад или делающую свой продукт. А там на собеседовании тебя будут спрашивать про MVC, ООП и фреймворки. Кстати, в нашем треде всему перечисленному учат.
#503 #436150
>>436072

Это не проблема так как \ не может быть частью имени переменной и php это понимает.

>>436074

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

>>436076

Там есть хитрость, ты можешь указать любой верхний предел, но mt_rand генерирует только числа типа int (причем наверняка только 32 битные), а они не могут быть меньше - 2 млрд или больше +2 млрд (примерно). тут есть примеры: http://php.net/manual/ru/language.types.integer.php

>>436078

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

То есть если ты имеешь код

function x() {
$a = 1; // создали локальную переменную
... действия с a ...
x( ); // рекурсия
...

то изменение переменной $a в одной функции никак не влияет на переменную $a в другой. Ты можешь поменять локальную переменную только внутри того вызова функции, который ее создал, и снаружи никак на нее не повлиять (и это делает код надежнее).

И если функция рекурсивно вызвана несколько раз, то существует несколько независимых переменных $a, каждая внутри своего вызова функции.
#503 #436150
>>436072

Это не проблема так как \ не может быть частью имени переменной и php это понимает.

>>436074

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

>>436076

Там есть хитрость, ты можешь указать любой верхний предел, но mt_rand генерирует только числа типа int (причем наверняка только 32 битные), а они не могут быть меньше - 2 млрд или больше +2 млрд (примерно). тут есть примеры: http://php.net/manual/ru/language.types.integer.php

>>436078

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

То есть если ты имеешь код

function x() {
$a = 1; // создали локальную переменную
... действия с a ...
x( ); // рекурсия
...

то изменение переменной $a в одной функции никак не влияет на переменную $a в другой. Ты можешь поменять локальную переменную только внутри того вызова функции, который ее создал, и снаружи никак на нее не повлиять (и это делает код надежнее).

И если функция рекурсивно вызвана несколько раз, то существует несколько независимых переменных $a, каждая внутри своего вызова функции.
#504 #436151
>>436084

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

>>436092

Есть годный учебник learn.javascript.ru и задачи от ОПа: https://gist.github.com/codedokode/ce30e7a036f18f416ae0

Для первых 10 задач есть робот-проверялка: http://dkab.github.io/jasmine-tests/

>>436094

Это пример кода на ООП. Если ты не знаком с ООП, в моем учебнике он объясняется в последнйе главе.

> Я немного не понял что выступает в качестве аргумента функции


Объект, на который указывает переменная $employee. Объекты можно хранить в переменных и передавать так же как и числа, строки или массивы. Разница только в том, что команда

$a = $b;

для объектов не делает в $a копию объекта $b, а копирует ссылку и 2 переменные укаызвают на тот же самый объект (в отличие от чисел, строк и массивов, для которых эта команда делает копию).

Заметь что там стоит тайп-хинт Employee который гарантирует что в функцию будет передан только объект класса Employee или его наследник. Тайп-хинты делают твой код надежнее и читаьельнее, используй их! Мануал: http://php.net/manual/ru/language.oop5.typehinting.php

> и в этом случае в массив $this->workers[] добавится уже посчитанные значения по кофе, зарплатам и страницам?


В массив добавляется объект, который внутри хранит информацию о работнике. зарплата нигде не хранится, она вычисляется функцией исходя из ранга и профессии работника.
#504 #436151
>>436084

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

>>436092

Есть годный учебник learn.javascript.ru и задачи от ОПа: https://gist.github.com/codedokode/ce30e7a036f18f416ae0

Для первых 10 задач есть робот-проверялка: http://dkab.github.io/jasmine-tests/

>>436094

Это пример кода на ООП. Если ты не знаком с ООП, в моем учебнике он объясняется в последнйе главе.

> Я немного не понял что выступает в качестве аргумента функции


Объект, на который указывает переменная $employee. Объекты можно хранить в переменных и передавать так же как и числа, строки или массивы. Разница только в том, что команда

$a = $b;

для объектов не делает в $a копию объекта $b, а копирует ссылку и 2 переменные укаызвают на тот же самый объект (в отличие от чисел, строк и массивов, для которых эта команда делает копию).

Заметь что там стоит тайп-хинт Employee который гарантирует что в функцию будет передан только объект класса Employee или его наследник. Тайп-хинты делают твой код надежнее и читаьельнее, используй их! Мануал: http://php.net/manual/ru/language.oop5.typehinting.php

> и в этом случае в массив $this->workers[] добавится уже посчитанные значения по кофе, зарплатам и страницам?


В массив добавляется объект, который внутри хранит информацию о работнике. зарплата нигде не хранится, она вычисляется функцией исходя из ранга и профессии работника.
#505 #436152
>>436122

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

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

>>436133

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

Заказчики в регионах предпочитают низкобюджетные простые сайты на CMS. Но есть например компании, делающие сложные приложения — там CMS не подходит.
#506 #436172
Помогите решить две проблемы:
1) Например в строке аа11134+54477+7-654+
регулярка preg_match_all("/[0-9]+[+0-9]+/", $str, $var);
не должна выдавать в конце +или -.
2) Туже самую строку нужно разбить на массив: число, +-, число, +- число...
#507 #436231
>>436172

> не должна выдавать в конце +или -.


перепиши регулярку чтобы было так:

(цифры-и-знаки)(цифра)

то есть чтобы в концце всегда была цифра.

Либо же исплоьзуй утверждения: http://php.net/manual/ru/regexp.reference.assertions.php

> Туже самую строку нужно разбить на массив: число, +-, число, +- число...


Напиши правильную регулярку. preg_split умеет с помощью специального флага сохранять разделители, то есть то что попало в регулярку.
187 Кб, 1280x853
#508 #436267
Аанасы, снова застрял в задачнике теперь про палиндром.
Я понятия не имею, что нужно писать в массиве, для того чтоб
выполнить проверку на палиндром.
http://ideone.com/7iCe3f
Это то что я накатал.
Это сама ссылка, чтоб долго не искать.
http://archive-ipq-co.narod.ru/l1/strings.html
Пикча для привлечения внимания.
#509 #436282
Начал делать задачки с кодфорсез http://codeforces.ru/problemset/problem/464/D

Сделал через ООП,
http://ideone.com/OMmQGE
но насколько я понял, чтобы высчитать вероятность как задано в задачке нужно повторить этот цикл большое количество раз и каждый раз высчитывать среднее арифметическое между старыми и новым результатом?
#510 #436335
Исправил вторую задачу http://jsfiddle.net/qrLdn0xe/
71 Кб, 640x671
#512 #436343
>>436131
>>436151
Спасибо, гайс.
#513 #436378
Пипец, я не могу даже решить задачу игры с кубиками. Сижу уже пол часа, посижу еще.
#514 #436379
Если мне сейчас дадут сразу готовый ответ, то это плохо скажется на моей обучаемости? Я просто даже не могу понять условие задачи.
47 Кб, 1160x431
#515 #436385
Ок, я хотя бы в правильном направлении иду?
#516 #436386
>>436378
>>436379
>>436385
Ты код вбрасывай, а тебе скажут в каком направлении двигаться.
#517 #436388
>>436386
Код так кидать?
<script src="http://ideone.com/e.js/IHlAEo" type="text/javascript" ></script>
#518 #436390
>>436388
Зачем так извращаться? Берешь урл из адресной строки и вставляешь сюда
http://ideone.com/IHlAEo
#519 #436391
>>436388

>PHP Fatal error: Call to undefined function eror_reporting() in /home/HIQDz9/prog.php on line 3


Всегда смотри на сообщения об ошибках.

>on line 3


На третьей строке ошибка.

>Call to undefined function eror_reporting()


Обращаешься к неизвестной функции eror_reporting(). Нет такой функции, есть функция error_reporting(), а ты написал с одной r
#520 #436393
>>436391
Ух ты, теперь работает. А где показываются сообщения об ошибках?
#521 #436394
>>436393
На айдеоне в stderr прямо под stdout. Сотри точку с запятой где-нибудь в коде и сам увидишь.
29 Кб, 1145x266
#523 #436413
Как анон мог победить, если у компа значение больше?
http://ideone.com/IHlAEo
#524 #436414
>>436413
А у тебя при проверке значение меньше стоит.
#525 #436416
>>436414
непонял
#526 #436420
>>436416

>$anonSum < $compSum

#527 #436421
>>436416
< - это знак меньше. У тебя в условии стоит $anonSum < $compSum
если сумма анона меньше суммы компьютера, анон победил.
#528 #436425
>>436421
А понял, но там такая проблема, я уже переделал, там абсолютно всегда была победа анона, даже когда у него меньше было.
#529 #436428
http://ideone.com/IHlAEo
Что теперь не так?
И когда я в прямом эфире редактирую по этой ссылке, то у вас тоже редактируется в прямом эфире или как?
#530 #436429
ААА ВСЕ Я СДЕЛАЛ САМ, ИЗВИНИТЕ ЗА БЕСПОКОЙСТВО.
#531 #436430
>>436425
Все работает же http://ideone.com/Rsbvff
>>436428
Не, у нас не редактируется "в прямом эфире"
#532 #436431
>>436428
?> в конце не нужно.
#533 #436432

>>>W4.2 Сделай рулетку, то есть генерируется 6-значный номер поста, и, в зависимости от последней цифры, что-то пишется (что, придумай сам).


Это надо в этой же программе что то менять или писать полностью новый код другой?
#534 #436433
>>436428

>И когда я в прямом эфире редактирую по этой ссылке, то у вас тоже редактируется в прямом эфире или как?


Когда ты нажимаешь редактировать и затем запускаешь код, то да, у нас он изменяется, если обновить страницу. Чтобы код оставался прежним, нужно вместо редактирования жать fork.
#535 #436435
>>436432
В каждой задаче нужен новый код.
#536 #436440
>>436435
Я имел в виду, что чтобы решить вторую задачу можно просто кое что поменять в этой или это совсем другая задача?
#537 #436443
>>436440
Ну а сам как думаешь? Начни делать, а там ясно будет.
#538 #436447
Зря я прошлые задачки не сохранил, они мне сейчас понадобились бы, я их забыл.
47 Кб, 1199x583
#539 #436452
Делаю рулетку.
#540 #436454
>>436267
Ну что же вы бетмены. Хоть Решение скиньте я сам разберусь.
#541 #436458
>>436454
У тебя там куча мелких ошибок, например отсутствует открывающая скобка, или нету закрывающей фигурной скобки. Смотри лог ошибок внизу, исправляй. Потом спросишь, что не понятно.
#542 #436463
>>436458
Да с этим я разберусь. Я просто логичесски "словами" не могу допереть как сравнивать буквы попарно.
Чтото вроде if $1=$-1 или что
#543 #436464
>>436463
Ты берешь первый символ с начала строки (это у тебя уже есть в коде), и первый символ с конца (чтобы понять как, еще раз прочитай про функцию mb_substr в уроке Опа) потом сравниваешь их друг с другом. Если они равны, цикл продолжается, если нет прерываешь его в результат записываешь, что строка не палиндром.
#544 #436465
http://ideone.com/IHlAEo
В чем проблема няши?
#545 #436468
>>436465
Проверка на равенство это ==, а = это присваивание. У тебя там в условиях переменная приравнивается к числу, а не сравнивается с ним.
#546 #436474
http://ideone.com/IHlAEo
Неужели я это сделал? Я!!! Обычное заводобыдло написал код!!! КРУТИМ РУЛЕТКУ
#547 #436517
>>436231

>(цифры-и-знаки)(цифра)


тогда в начали будет пропускать знак, с утверждениями буду разбираться,
> preg_split умеет с помощью специального флага сохранять разделители
не нашел нужный флаг
#548 #436520
>>436282
http://ideone.com/kuw7jW
добавил строку продажи нового предмета если он хуже чем старый
#549 #436521
>>436474
Это зделал не ты. Ты просто подставил значения по инструкции, уебушек.
#550 #436561
Фух! Сделал задачку написания чисел прописью. Я у мамы молодец?
http://ideone.com/6jj9fm
#551 #436590
>>436561
Как далеко ты зашел?
>>436474 кун
#553 #436596
>>436267

Берешь первый с начала и первый с конца символы, сравниваешь. Если не совпали — не палиндром, если совпали — сравниаем дальше.

Берешь 2й с начала и 2й с конца символы, сравниваешь. Если не совпали — не палиндром, если совпали — сравниаем дальше.

....

Берешь N-й с начала и N-й с конца символы, сравниваешь. Если не совпали — не палиндром, если совпали — сравниаем дальше.

Если дошли до середины строки не несовпадений не было — значит палиндром.

>>436282

> чтобы высчитать вероятность как задано в задачке нужно повторить этот цикл большое количество раз и каждый раз высчитывать среднее арифметическое между старыми и новым результатом?


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

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

Альтернативный метод — не проводить эксперимент, а рассчитать матожидание математически. Ну например в задаче «определите матожидание числа выпавшего на кубике» вместо проведения реального эксперимента можно заметить, что цифры 1-6 выпадают с равной веростностью и матожидание будет равно (1 + 2 .... + 6) / 6 = 3.5. Это точный ответ, а если бы мы проводили эксперимент (попробуй сам), то мы бы получили неточное число вроде 3.5012

В условии задачи сказано:

> Ответ считается правильным, если его относительная или абсолютная погрешность не превосходит 10^ 9.



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

Ну к примеру, давай найдем матожидание заработанных денег после одного хода. В начале мы имеем k вещей 1-го уровня:

1 1 1 1 ... 1

После первого хода мы убиваем монстра и получаем одну вещь случайного типа случайного уровня из диапазона [1, 2], то есть либо первого либо второго уровня.

— если мы получаем вещь первого уровня, мы ее продаем за одну монету
— если второго уровня, то оставляем ее себе и продаем имеющуюся за 1 монету

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

Я бы изобразил это так:

1×0.5 + 2×0.5 1 1 1 ... 1

1 × 0.5 + 2 x 0.5 здесь значит что в половине случаев там вещь 1-го уровня, в половине 2-го.

Теперь рассчитаем ситуацию после второго хода. Убив монстра, мы получаем вещь случайного типа. В 1/2k случаев вещь такого типа (L2) у нас есть, причем 2-го уровня, и в оставшихся (2k - 1)/2k случаев у нас есть такая вещь первого уровня.

Таким образом после второго хода есть такие исходы:

Если у нас есть L2 и нам выпадает вещь такого же типа:

- мы получаем вещь типа L 3-го уровня (L3) и продаем имеющуюся L2 за 2 монеты. Это происходит в (1/2k / 3) случаев.
- мы получаем новую вещь 2-го уровня и продаем L2 за 2 монеты
- мы получаем новую вещь 1-го уровня и продаем ее за 1 монету

Если у нас нет L2 или есть, но выпадает вещь другого типа:

- мы либо получаем вещь 1 уровня и продаем ее за 1 монету
- либо получаем вещь 2 уровня и продаем существующую за 1 монету

То есть у нас после 2 хода есть уже 5 вариантов исходов с разной вероятностью. Перемножив и сложив их, мы получим матожидание числа монет после 2-го хода.

Что касается вещей, то большинство вещей у нас будут 1-го уровня, и только 2 вещи могут быть 2-го, либо одна вещь 3-го уровня.

Как мы видим, на каждом ходе число возможных исходов увеличивается (есть наука комбинаторика, которая может посчитать сколько исходов будет через N ходов). Так как вещей K и к N-му ходу у нас могут быть вещи не выше N + 1 уровня, то для хранения информации о вероятностях обладания вещью понадобится массив размером k × (n + 1) что приемлемо (с учетом ограничения в 1 ≤ n ≤ 10^5; 1 ≤ k ≤ 100 в массиве не может быть более 10 ^ 5 × 100 = 10 млн элементов).

Очевидно, программа должна работать по такой логике и рассчитывать итоговую ситуацию через N ходов. Я не уверен, сколько действий надо сделать для расчета всех вариантов и нужны ли здесь какие-то оптимизации или решение «перебрать и сложить все варианты» в лоб подойдет. Для этого надо анализировать задачу дополнительно. Скорее всего нужны, так как если у нас есть массив k × N то чтобы его обновить надо сделать k × N действий и за N ходов это будет k × N ^ 2 действий, что довольно много.

Продолжу в след. посте.
#553 #436596
>>436267

Берешь первый с начала и первый с конца символы, сравниваешь. Если не совпали — не палиндром, если совпали — сравниаем дальше.

Берешь 2й с начала и 2й с конца символы, сравниваешь. Если не совпали — не палиндром, если совпали — сравниаем дальше.

....

Берешь N-й с начала и N-й с конца символы, сравниваешь. Если не совпали — не палиндром, если совпали — сравниаем дальше.

Если дошли до середины строки не несовпадений не было — значит палиндром.

>>436282

> чтобы высчитать вероятность как задано в задачке нужно повторить этот цикл большое количество раз и каждый раз высчитывать среднее арифметическое между старыми и новым результатом?


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

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

Альтернативный метод — не проводить эксперимент, а рассчитать матожидание математически. Ну например в задаче «определите матожидание числа выпавшего на кубике» вместо проведения реального эксперимента можно заметить, что цифры 1-6 выпадают с равной веростностью и матожидание будет равно (1 + 2 .... + 6) / 6 = 3.5. Это точный ответ, а если бы мы проводили эксперимент (попробуй сам), то мы бы получили неточное число вроде 3.5012

В условии задачи сказано:

> Ответ считается правильным, если его относительная или абсолютная погрешность не превосходит 10^ 9.



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

Ну к примеру, давай найдем матожидание заработанных денег после одного хода. В начале мы имеем k вещей 1-го уровня:

1 1 1 1 ... 1

После первого хода мы убиваем монстра и получаем одну вещь случайного типа случайного уровня из диапазона [1, 2], то есть либо первого либо второго уровня.

— если мы получаем вещь первого уровня, мы ее продаем за одну монету
— если второго уровня, то оставляем ее себе и продаем имеющуюся за 1 монету

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

Я бы изобразил это так:

1×0.5 + 2×0.5 1 1 1 ... 1

1 × 0.5 + 2 x 0.5 здесь значит что в половине случаев там вещь 1-го уровня, в половине 2-го.

Теперь рассчитаем ситуацию после второго хода. Убив монстра, мы получаем вещь случайного типа. В 1/2k случаев вещь такого типа (L2) у нас есть, причем 2-го уровня, и в оставшихся (2k - 1)/2k случаев у нас есть такая вещь первого уровня.

Таким образом после второго хода есть такие исходы:

Если у нас есть L2 и нам выпадает вещь такого же типа:

- мы получаем вещь типа L 3-го уровня (L3) и продаем имеющуюся L2 за 2 монеты. Это происходит в (1/2k / 3) случаев.
- мы получаем новую вещь 2-го уровня и продаем L2 за 2 монеты
- мы получаем новую вещь 1-го уровня и продаем ее за 1 монету

Если у нас нет L2 или есть, но выпадает вещь другого типа:

- мы либо получаем вещь 1 уровня и продаем ее за 1 монету
- либо получаем вещь 2 уровня и продаем существующую за 1 монету

То есть у нас после 2 хода есть уже 5 вариантов исходов с разной вероятностью. Перемножив и сложив их, мы получим матожидание числа монет после 2-го хода.

Что касается вещей, то большинство вещей у нас будут 1-го уровня, и только 2 вещи могут быть 2-го, либо одна вещь 3-го уровня.

Как мы видим, на каждом ходе число возможных исходов увеличивается (есть наука комбинаторика, которая может посчитать сколько исходов будет через N ходов). Так как вещей K и к N-му ходу у нас могут быть вещи не выше N + 1 уровня, то для хранения информации о вероятностях обладания вещью понадобится массив размером k × (n + 1) что приемлемо (с учетом ограничения в 1 ≤ n ≤ 10^5; 1 ≤ k ≤ 100 в массиве не может быть более 10 ^ 5 × 100 = 10 млн элементов).

Очевидно, программа должна работать по такой логике и рассчитывать итоговую ситуацию через N ходов. Я не уверен, сколько действий надо сделать для расчета всех вариантов и нужны ли здесь какие-то оптимизации или решение «перебрать и сложить все варианты» в лоб подойдет. Для этого надо анализировать задачу дополнительно. Скорее всего нужны, так как если у нас есть массив k × N то чтобы его обновить надо сделать k × N действий и за N ходов это будет k × N ^ 2 действий, что довольно много.

Продолжу в след. посте.
#554 #436602
>>436282

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

Вещь я буду обозначать так: B3 - вещь второго типа 3-го уровня.

Я буду рисовать таблицу из 4 вещей максимум 3 уровня.

До первого хода мы имеем все вещи 1-го уровня и таблица имеет вид:

0 0 0 0
0 0 0 0
1 1 1 1
A B C D

То есть у нас есть 4 вещи 1-го уровня. Вероятность иметь вещь второго уровня равна нулю.

После первого хода мы с вероятностью 0.5 имеем одну из вещей второго уровня и с вероятностью 0.5 остаемся со старой. Для простоты предположим что эта вещь всегда первого типа (то есть мы назовем первую полученную вещь A). То есть мы получаем либо A1 либо A2 с равной вероятностью. Таблица выглядит так:

0.0 0 0 0
1/2 0 0 0
1/2 1 1 1
-A- B C D

То есть в половине случаев мы имеем 1 вещь 2 уровня и 3 вещи первого, и в половине у нас все вещи первого уровня.

После второго хода, мы можем получить вещь такого же как в прошлый раз (A) или другого (B) типа. И она может быть 1-3 уровней для первого типа, и 1-2 уровней для второго. Получается более сложная картина:

- в 1/4 случаев мы получаем вещь A, такую же как и в первый ход. При этом она может быть 1, 2, 3 уровня с разной вероятностью. Вероятность получить вещь A имея A1 равна 1/8. Вероятночть получить A имея A2 равна 1/8. Если у нас есть A2, мы можем получить A1-A3 (вероятность 1/8 распределяется поровну на эти 3 варианта), а если нету то только A1 или A2 (1/8 делится на 2 варианта).

Поделив вероятности получаем в итоге после второго хода вероятность получить:

A1 имея A1 = 1/16
A2 имея A1 = 1/16
A1 имея A2 = 1/24
A2 имея A2 = 1/24
A3 имея A2 = 1/24
B1 или 2 имея A1 = 3/4/ 2= 3/8
B1 или 2 имея A2 = 3/8

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

A1 c вероятностью 1/16 + 3/8
A2 с вероятностью 1/16 + 1/24 + 1/24 + 3/8
A3 c вероятностью 1/24

Что каается вероятности получить B2, она равна 3/4 /2 = 3/8

Таким образом мы можем составить таблицу вероятности владеть вещью определенного уровня после 2 хода (я посчитал сумму дробей на wolphram alpha):

https://gist.github.com/anonymous/95aeedeac668c9b15737

Наверно, это сложно, но главное что можно понять:

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

Соответственно на такой логике можно попробовать сделать программу. Единтвенное, что мне кажется, тут могут понадобиться дальнейшие оптимизации, так как иначе действий придется сделать очень много и можно не уложиться по времени. Может быть можно найти какую-то особенность и упростить расчет.
#554 #436602
>>436282

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

Вещь я буду обозначать так: B3 - вещь второго типа 3-го уровня.

Я буду рисовать таблицу из 4 вещей максимум 3 уровня.

До первого хода мы имеем все вещи 1-го уровня и таблица имеет вид:

0 0 0 0
0 0 0 0
1 1 1 1
A B C D

То есть у нас есть 4 вещи 1-го уровня. Вероятность иметь вещь второго уровня равна нулю.

После первого хода мы с вероятностью 0.5 имеем одну из вещей второго уровня и с вероятностью 0.5 остаемся со старой. Для простоты предположим что эта вещь всегда первого типа (то есть мы назовем первую полученную вещь A). То есть мы получаем либо A1 либо A2 с равной вероятностью. Таблица выглядит так:

0.0 0 0 0
1/2 0 0 0
1/2 1 1 1
-A- B C D

То есть в половине случаев мы имеем 1 вещь 2 уровня и 3 вещи первого, и в половине у нас все вещи первого уровня.

После второго хода, мы можем получить вещь такого же как в прошлый раз (A) или другого (B) типа. И она может быть 1-3 уровней для первого типа, и 1-2 уровней для второго. Получается более сложная картина:

- в 1/4 случаев мы получаем вещь A, такую же как и в первый ход. При этом она может быть 1, 2, 3 уровня с разной вероятностью. Вероятность получить вещь A имея A1 равна 1/8. Вероятночть получить A имея A2 равна 1/8. Если у нас есть A2, мы можем получить A1-A3 (вероятность 1/8 распределяется поровну на эти 3 варианта), а если нету то только A1 или A2 (1/8 делится на 2 варианта).

Поделив вероятности получаем в итоге после второго хода вероятность получить:

A1 имея A1 = 1/16
A2 имея A1 = 1/16
A1 имея A2 = 1/24
A2 имея A2 = 1/24
A3 имея A2 = 1/24
B1 или 2 имея A1 = 3/4/ 2= 3/8
B1 или 2 имея A2 = 3/8

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

A1 c вероятностью 1/16 + 3/8
A2 с вероятностью 1/16 + 1/24 + 1/24 + 3/8
A3 c вероятностью 1/24

Что каается вероятности получить B2, она равна 3/4 /2 = 3/8

Таким образом мы можем составить таблицу вероятности владеть вещью определенного уровня после 2 хода (я посчитал сумму дробей на wolphram alpha):

https://gist.github.com/anonymous/95aeedeac668c9b15737

Наверно, это сложно, но главное что можно понять:

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

Соответственно на такой логике можно попробовать сделать программу. Единтвенное, что мне кажется, тут могут понадобиться дальнейшие оптимизации, так как иначе действий придется сделать очень много и можно не уложиться по времени. Может быть можно найти какую-то особенность и упростить расчет.
#555 #436605
>>436282

Теперь разберем твое решение.

Видно что твоя программа делает ровно 1 эксперимент и потому погрешность будет огромная, явно больше чем 10 ^ -9 . Мне кажется, так ты задачу за разумное время не решишь. Тут нужен математический подход.

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

Насчет codeforces: там у каждой задачи указано число человек которые ее решили. Вот можно отсортировать список по количеству: http://codeforces.ru/problemset?order=BY_SOLVED_DESC

А вещь твою задачу решили всего 166 человек. Я бы советовал начинать с тех что решили хотя бы 3000 человек.

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

Ну и по коду, примерно такие замечания:

> public $hero;


Переходи на protected/private свойства, public исплоьзовался только в первых задачах ради простоты, а дальше стоит исплоьзовать закрытые свойства.

> \tpublic $gold=0;


Число золота — это наверно свойство героя, а не игры?

get значит «получить». Не надо его к каждой функии приписывать:

getKillMonster -> killMonster
getChangeItem -> changeItem, replaceItem, sellItem

> $monsters = $this->monsters; //копия переменной монстров


Незачем делать копию

Строки 22-28 стоит перенести в класс Hero.

> \t$item = new Item($i);


> $items[] = $item;


Тут можно ключом массива сделать тип вещи, для более удобного поиска.

> getOldItem($numberItem)


Удобнее если функцию будет возвращать объект-вещь, а не уровень.Это гибче.

> public function getChangeItem($numberItem, $itemLvl)


тут тоже логичнее сделать replaceItem(Item $old, Item $new)

> function getGame($n, $k)


Не нужна

В общем, подведу итог:

- если ты хочешь решать олимпиадные задачки, начни с более простых и читай теорию (если не уверен, дай ссылки на статьи/учебники я скажу какой больше тебе подойдет)
- если хочешь помучать ООП, решай кошки-мышки
#555 #436605
>>436282

Теперь разберем твое решение.

Видно что твоя программа делает ровно 1 эксперимент и потому погрешность будет огромная, явно больше чем 10 ^ -9 . Мне кажется, так ты задачу за разумное время не решишь. Тут нужен математический подход.

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

Насчет codeforces: там у каждой задачи указано число человек которые ее решили. Вот можно отсортировать список по количеству: http://codeforces.ru/problemset?order=BY_SOLVED_DESC

А вещь твою задачу решили всего 166 человек. Я бы советовал начинать с тех что решили хотя бы 3000 человек.

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

Ну и по коду, примерно такие замечания:

> public $hero;


Переходи на protected/private свойства, public исплоьзовался только в первых задачах ради простоты, а дальше стоит исплоьзовать закрытые свойства.

> \tpublic $gold=0;


Число золота — это наверно свойство героя, а не игры?

get значит «получить». Не надо его к каждой функии приписывать:

getKillMonster -> killMonster
getChangeItem -> changeItem, replaceItem, sellItem

> $monsters = $this->monsters; //копия переменной монстров


Незачем делать копию

Строки 22-28 стоит перенести в класс Hero.

> \t$item = new Item($i);


> $items[] = $item;


Тут можно ключом массива сделать тип вещи, для более удобного поиска.

> getOldItem($numberItem)


Удобнее если функцию будет возвращать объект-вещь, а не уровень.Это гибче.

> public function getChangeItem($numberItem, $itemLvl)


тут тоже логичнее сделать replaceItem(Item $old, Item $new)

> function getGame($n, $k)


Не нужна

В общем, подведу итог:

- если ты хочешь решать олимпиадные задачки, начни с более простых и читай теорию (если не уверен, дай ссылки на статьи/учебники я скажу какой больше тебе подойдет)
- если хочешь помучать ООП, решай кошки-мышки
#556 #436609
>>436335

Ошибки:

- цвет не тот. Определить цвет можно инструментом пипетка в графическом редакторе по скриншоту либо еще как-то. Верстальщик должен уметь это делать.

- Шрифт у тебя с засечками, а надо без (например Arial подойдет или Trebuchet MS)

- Максимальная ширина блока должна быть 600 px а у тебя 622 (это можно проверить инспектором Ctrl + Shift + I на вкладке Elements, там есть схема с размерами блока) так как width задает ширину без учета паддинга и border. Читал ли ты внимательно статью? http://htmlbook.ru/samlayout/blochnaya-verstka/blochnaya-model

>>436340

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

>>436378

Покажи код
@
Попроси подсказку

>>436379

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

Не понял условие — уточни.

>>436385

Да, только почему у тебя побеждает тот у кого очков меньше?

>>436388

Гуд, (теперь) все верно.

>>436393

Они выводтся в пункте stderr, но если ты нажал edit и запускаешь программу там, то там ошибки не выводятся. Жми fork вместо edit и все будет нормально.

Отписал про баг разработчикам ideone.
#556 #436609
>>436335

Ошибки:

- цвет не тот. Определить цвет можно инструментом пипетка в графическом редакторе по скриншоту либо еще как-то. Верстальщик должен уметь это делать.

- Шрифт у тебя с засечками, а надо без (например Arial подойдет или Trebuchet MS)

- Максимальная ширина блока должна быть 600 px а у тебя 622 (это можно проверить инспектором Ctrl + Shift + I на вкладке Elements, там есть схема с размерами блока) так как width задает ширину без учета паддинга и border. Читал ли ты внимательно статью? http://htmlbook.ru/samlayout/blochnaya-verstka/blochnaya-model

>>436340

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

>>436378

Покажи код
@
Попроси подсказку

>>436379

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

Не понял условие — уточни.

>>436385

Да, только почему у тебя побеждает тот у кого очков меньше?

>>436388

Гуд, (теперь) все верно.

>>436393

Они выводтся в пункте stderr, но если ты нажал edit и запускаешь программу там, то там ошибки не выводятся. Жми fork вместо edit и все будет нормально.

Отписал про баг разработчикам ideone.
#557 #436610
>>436411

ого, я смотрю, что-то часто даблы выпадают.

>>436428

Если ты жмешь edit то редактируется у всех
Если fork то создается новый код по новой ссылке.

Лучше жать fork.

>>436430

> elseif ($anonSum = $compSum) {


Ошибка:

= значит поместить значение в переменную
== сравнить 2 значения

Ты не сравниваешь, а копируешь в anonSum значение переменной compSum

Всегда пиши == внутри if, а не =

Ну и в данном случае можно просто написать else без условия так как 4-го варианта не дано.
#558 #436613
>>436432

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

>>436440

Ну а ты попробуй и посмотри что получится.

>>436447

Реши заново. Второй раз быстрее же будет.

>>436452

Начало неплохое

>>436463

написал тут >>436596

>>436474

Да, все верно.

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

Ну и решения на проверку не забывай показывать.

>>436517

>> preg_split умеет с помощью специального флага сохранять разделители


> не нашел нужный флаг



Посмотри код, все разделители попали в массив: http://ideone.com/r3sdx8

>>436521

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

>>436561

Посмотри внизу куча ошибок:

> PHP Warning: Missing argument 2 for smallNumberToText(), called in /home/Oueapy/prog.php on line 107 and defined in /home/Oueapy/prog.php on line 29


> PHP Notice: Undefined variable: isFemale in /home/Oueapy/prog.php on line 48



Их надо исправить.

Также надо исправить все замечания из поста: >>436147

Если что-то непонятно, задавай вопросы.
#558 #436613
>>436432

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

>>436440

Ну а ты попробуй и посмотри что получится.

>>436447

Реши заново. Второй раз быстрее же будет.

>>436452

Начало неплохое

>>436463

написал тут >>436596

>>436474

Да, все верно.

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

Ну и решения на проверку не забывай показывать.

>>436517

>> preg_split умеет с помощью специального флага сохранять разделители


> не нашел нужный флаг



Посмотри код, все разделители попали в массив: http://ideone.com/r3sdx8

>>436521

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

>>436561

Посмотри внизу куча ошибок:

> PHP Warning: Missing argument 2 for smallNumberToText(), called in /home/Oueapy/prog.php on line 107 and defined in /home/Oueapy/prog.php on line 29


> PHP Notice: Undefined variable: isFemale in /home/Oueapy/prog.php on line 48



Их надо исправить.

Также надо исправить все замечания из поста: >>436147

Если что-то непонятно, задавай вопросы.
#559 #436651
Хорошие новости: яндекс видимо переходит на PHP и ищет php-разработчика: http://company.yandex.ru/job/vacancies/phpdev_market.xml

Ну и конечно яндекс не забыл добавить пункт про эллиптические функции. Вряд ли их там кто-то использует, просто видимо повыпендриваться хотят какие они умные.
#560 #436683
>>436605

> $monsters = $this->monsters; //копия переменной монстров


>Незачем делать копию


Если не делать - у меня ниже идет цикл где использовано это свойство:
for ($i = 1; $i <= $this->monsters; $i++)
А в теле цикла декремент использован на это свойство $this->monsters. То-бишь мне надо либо использовать копию свойства либо переделывать цикл.
#561 #436698
Вопрос по ООП:
Если свойствами одного объекта является массив двух и больше объектов - можно ли как нибудь напрямую обращаться к одному из объектов без перебора всего массива через foreach ?
#562 #436701
>>436698
По ключу?
#563 #436717
>>436701
Ну вот к примеру у меня есть экземпляр объекта
$game, внутри объекта есть массив $players в котором находятся экземпляры объектов $player.
я пробовал обращаться к ним через $game->players->0 - не выходит.
#564 #436718
>>436717

>$game->players[0]

#565 #436719
>>436717

$game->players[0]

[] используются для выбора элемета из массива
-> для обращения к свойсту или методу

И наоборот, если у тебя массив объектов то пиши

$palyers[0]->doSmth( );
#566 #436741
>>436719
>>436718
Спасибо.
Сделал тут симулятор боя из браузерной игрушки

http://ideone.com/wpVMXX
нужна критика.
#567 #436746
>>436741

Копипаста — зло.

Нельзя ли функции makeOneHitFirstHero и makeOneHitSecondHero которые почти одинаковы, заменить на одну универсальную, в которую передается кто кого атакует?
#568 #436747
>>436746
Это был обходной путь - выше я как раз спрашивал как обратиться к объектам напрямую так как не знал, эт уже позже переделаю.
#569 #436748
>>436741

Еще мне кажется, если урон нанести не удалось, то надпись

> DoctorS наносит 0 урона.



можно не выводить.
#570 #436749
>>436748
Там вроде в самой браузерке выводится.
32 Кб, 800x547
#571 #436757
>>436267
http://ideone.com/lIOFhk
Всё парюсь с зад чей про палиндром. Почти додумался но теперь выходит непонятная хрень портящая всю малину.
Почему при разборе по буквам фразы с конца два раза проверяется буква А.
#572 #436760
>>436757
Внимательнее посмотри на $symbol2. Какой символ будет при каждой итерации цикла выводится?
#574 #436764
>>436741

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

Плохо, что в конструкторе очень много параметров. Ты не должен делать в функции больше 4-5 аргументов. Это неудобно так как когда ты смотришь на код

> new Hero('DoctorS', 504, 563, 19520, 225, 276, 39, 25, 51, 1276);



Непонятно, какая цифра что значит. В такой ситуации лучше сделать создание героя в несколько шагов:

$doctor = new Hero('DoctorS', 19520);
$doctor->setAttackRange(503, 563);
$doctor->setArmorRange(100, 200);

Или, можно использовать запись в виде цепочки если в конце функций сделать return $this:

$doctor->setAttackRange(...)->
setArmor(...)->
setBlockProbability(...);

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

Еще одним способом сделать код понятнее будет передача массива в конструктор:

$doctor = new Hero('DoctorS', [
'attackLow' => 100,
'attackHigh' => 200,
'armorLow' => 100,
...
]);

За счет массива видно какая цифра что обозначает.

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

> $critAmplify = 1;


> return $critAmplify;


Не проще ли написать return 1; не заводя переменную? Аналогично, тут:

> $reduction = mt_rand($this->armorLow, $this->armorHigh);


> return $reduction;



можно сразу писать return mt_rand....

> onstruct($heroFirst, $heroSecond)


Исплоьзуй тайп хинты везде где можно: http://php.net/manual/ru/language.oop5.typehinting.php

Они делают твой код понятнее и надежнее.

Непонятна логика почему getCrit возвращает 1 или 2, а getBlock 0 или 1. Если у тебя результат вида да/нет то лучше всего использовать значения false/true которые специально для этого придуманы ( http://php.net/manual/ru/language.types.boolean.php ) ну или хотя бы 0/1.

Тогда вместо непоянтного

if ($crit == 2)

можно написать читабельное

if ($isCriticalAttack) ...

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

$damage = $target->reduceDamage($damage);

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

> $block = $this->heroFirst->getBlock( );


Тут по моему должно быть heroSecond? Он же удар блокирует.

> $this->heroSecond->doubleHit


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

if ($hero->canHitAgain($target)) ...

Ты не должен хранить doubleHit как свойство, так как это не свойство одного героя, а величина которая получается при сравнении характеристик 2 героев. Ее неправильно хранить как свойство.

> if (!isset($damage2)) {


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

> $this->heroFirst->health -= $secondDmg;


Лучше сделать метод $hero->takeDamage($damage)

Также, лучше исплоьзовать свойства c доступом private/protected, то есть закрыть их от доступа извне. Это делает код надежнее и получается меньше бардака, так как в этом случае свойства можно менять только через методы.

Соответственно вместо этого

> if ($this->heroFirst->health == 1) {


Лучше написать if ($hero->isDead()) так как это переносит алгоритм определения смерти в класс героя и позволяет сделать его более гибким. Ну и читается праивльнее. Кстати, в мое время герои умирали при достижении 0 HP, а не 1.

> if ($firstFullDmg > $secondFullDmg) {


Странно, ты проверяешь кто победил по тому кто нанес больше урона, а надо проверять у кого осталось меньше HP. А ничья если оба живы остались наверно?
#574 #436764
>>436741

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

Плохо, что в конструкторе очень много параметров. Ты не должен делать в функции больше 4-5 аргументов. Это неудобно так как когда ты смотришь на код

> new Hero('DoctorS', 504, 563, 19520, 225, 276, 39, 25, 51, 1276);



Непонятно, какая цифра что значит. В такой ситуации лучше сделать создание героя в несколько шагов:

$doctor = new Hero('DoctorS', 19520);
$doctor->setAttackRange(503, 563);
$doctor->setArmorRange(100, 200);

Или, можно использовать запись в виде цепочки если в конце функций сделать return $this:

$doctor->setAttackRange(...)->
setArmor(...)->
setBlockProbability(...);

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

Еще одним способом сделать код понятнее будет передача массива в конструктор:

$doctor = new Hero('DoctorS', [
'attackLow' => 100,
'attackHigh' => 200,
'armorLow' => 100,
...
]);

За счет массива видно какая цифра что обозначает.

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

> $critAmplify = 1;


> return $critAmplify;


Не проще ли написать return 1; не заводя переменную? Аналогично, тут:

> $reduction = mt_rand($this->armorLow, $this->armorHigh);


> return $reduction;



можно сразу писать return mt_rand....

> onstruct($heroFirst, $heroSecond)


Исплоьзуй тайп хинты везде где можно: http://php.net/manual/ru/language.oop5.typehinting.php

Они делают твой код понятнее и надежнее.

Непонятна логика почему getCrit возвращает 1 или 2, а getBlock 0 или 1. Если у тебя результат вида да/нет то лучше всего использовать значения false/true которые специально для этого придуманы ( http://php.net/manual/ru/language.types.boolean.php ) ну или хотя бы 0/1.

Тогда вместо непоянтного

if ($crit == 2)

можно написать читабельное

if ($isCriticalAttack) ...

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

$damage = $target->reduceDamage($damage);

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

> $block = $this->heroFirst->getBlock( );


Тут по моему должно быть heroSecond? Он же удар блокирует.

> $this->heroSecond->doubleHit


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

if ($hero->canHitAgain($target)) ...

Ты не должен хранить doubleHit как свойство, так как это не свойство одного героя, а величина которая получается при сравнении характеристик 2 героев. Ее неправильно хранить как свойство.

> if (!isset($damage2)) {


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

> $this->heroFirst->health -= $secondDmg;


Лучше сделать метод $hero->takeDamage($damage)

Также, лучше исплоьзовать свойства c доступом private/protected, то есть закрыть их от доступа извне. Это делает код надежнее и получается меньше бардака, так как в этом случае свойства можно менять только через методы.

Соответственно вместо этого

> if ($this->heroFirst->health == 1) {


Лучше написать if ($hero->isDead()) так как это переносит алгоритм определения смерти в класс героя и позволяет сделать его более гибким. Ну и читается праивльнее. Кстати, в мое время герои умирали при достижении 0 HP, а не 1.

> if ($firstFullDmg > $secondFullDmg) {


Странно, ты проверяешь кто победил по тому кто нанес больше урона, а надо проверять у кого осталось меньше HP. А ничья если оба живы остались наверно?
#575 #436766
>>436761
Спасибо у меня в голове не укладывалось, что можно прибавить отнять.
>>436760
Смотрю книгу вижу фигу
От текста $nText1 -0 символ(вот это звучит бредово да )
#576 #436768
>>436764

>Непонятна логика почему getCrit возвращает 1 или 2, а getBlock 0 или 1. Если у тебя результат вида да/нет то лучше всего использовать значения false/true


Я их там дальше при подсчете одной атаки использую в качестве множителей.
Крит умножает атаку на 2, в то же время блок врага умножает атаку на 0. На выходе получаю либо либо х2 либо х1 урон если блока не было, если блок был - получаю 0.
#577 #436770
>>436749

Может это программисты поленились.

>>436757

> Тут меня беспокоит, что я ввёл 2 новые


> переменные можноли их не вводить?


Можно не вводить, можно положить текст назад в ту же переменную:

$text = str_replace($text, ....);

Но если ты вводишь новые переменные, надо давать им понятные имена. Вот полезный урок на тему как (не) надо называть переменные: http://learn.javascript.ru/write-unmain-code#именование

В твоем случае новая переменная содержит текст без пробелов и ее уместно назвать textWithoutSpaces (или просто положить результат назад в text)

> А тут я понятия не имею что делать?


Сравни буквы, и если они не совпадают, выходи из цикла — слово не палиндром. Если же все буквы совпали, слово палиндром.
#578 #436771
>>436766
Посмотри у тебя там код не проверяет действительно ли $symbol равняется $symbol2 и в результате просто пишет, что они одно и то же.
#579 #436772
>>436757

чтобы взять 1-й с конца символ надо писать

mb_susbtr($x, -1, 1);

А ты пишешь

mb_substr($x, 0, 1)

и получаешь первый с начала.

>>436768

Лучше true/fasle, а в расчет использовать например

if ($critical) {
$damage ×= 2;
}

или

$damage = ... × ($critital? 2 : 1);
#580 #436775
>>436764
Ввод данных для создания экземпляра класса Hero да большой, но это идет не как часть самой браузерки, это скорее как сторонний скрипт который поможет определить - стоит ли нападать либо нет, если цикл боев повторить раз 100-1000 можно получить средний шанс на победу с большой погрешностью конечно. В принципе можно в html создать окно для ввода необходимых параметров своего и вражеского персонажа и на выходе получить вероятность победы. А остальные замечанию постараюсь поправить, благодарю.
228 Кб, 778x554
#581 #436778
>>436772
>>436771
>>436772
Спасибо всем за оперативную помощь. Таки разобрался.
Нефти нет плачу хлебушком.
87 Кб, 987x626
#582 #436779

>>>Выполни код на картинке


Всмысле просто перепечатать?

>>>Как-нибудь его поменяй


Например как?
#583 #436782
http://ideone.com/zOliGn
Так сойдет? Я справился с заданием?
#584 #436785
>>436779

Например сделай программу чтобы выводился такой текст:

осталось: 10
осталось: 9
осталось: 8
...
осталось: 0

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

>>436782

ты прямо мою мысль прочитал. Да, сойдет.
#585 #436787
Я понимаю, что можно сделать так, чтобы "Пуск поехали" было не само по себе, а именно когда дойдет до однерки, как условие, но немогу сделать, хотя так наверно правильнее будет.
#586 #436788
Хотя вроде получилось http://ideone.com/zOliGn
#587 #436789
>>436788
А нет
#588 #436791
А нет все понял.
Поставил if($i=0) и ракета не запустилась
#589 #436793
>>436787

Не стоит усложнять программу без надобности. А вообще, могжно сделать с помощью if

>>436788

- if должен быть внутри цикла а не снаужи
- в if надо использовать == для сравнения. а не =
#591 #436800
>>436795

Ты неправильно пишешь. Внутри if надо писать ==, а не = для сравнения. В твоем случае проще вообще без if написать echo.
#592 #436801
>>436793
Что теперь не так?
Почему >=1 не работает с 1, а только когда стоит 0, ведь 1=1
http://ideone.com/zOliGn
#593 #436803
То есть
$i >= 1 не работает с if($i == 1), а
$i >= 1 работает с if($i == 0)

Ведь 1=1
#594 #436805
>>436801

Поставь перед

> if($i == 1) {



Команду echo "i=$i\n"; чтобы увидеть чему равно i перед выполнением if.
#595 #436809
>>436805

>>> "i=$i\n";


Как называется эта функция?
#596 #436811
#597 #436817
>>436809

Это ты просто выводишь чему равно i, "i=" это текст, а $i это имя переменной. Посмотри, там внизу написано

i = 0

Это происходит потмоу что после цикла i равно 0. Почему? надо разобрать, как работает цикл.

Допустим, что сейчас i = 2. Разберем что происходит в цикле:

- проверяется выполнено ли условие $i >= 1 (да)
- выполняется тело цикла
- выполняется команда $i-- и $i становится равным 1
- проверяется выполнено ли условие $i >= 1 (да)
- выполняется тело цикла
- выполняется команда $i-- и $i становится равным 0
- проверяется выполнено ли условие $i >= 1 (нет)
- цикл завершен, а в $i хранится 0
#598 #436818
>>436809

так как после завершения цикла i равно нулю, условие

> if($i == 1) {



Не срабатывает.

В твоем случае, по моему проще вообще убрать if и просто написать

echo "Поехали";
#599 #436819
>>436818
Я об этом писал ранее, твой вариант как бы неживой. Ну типо слово поехали будет в любом случае. А я хочу, чтобы слово поехали было именно тогда когда выполняется команда $i >= 1
#600 #436821
>>436819

Тогда поставь if внутри тела цикла (то ест внутри скобочек for { ... }), а не после. Внутри цикла на последнем шаге $i как раз равно единице и условие сработает.
#601 #436825
>>436821
http://ideone.com/zOliGn
Неполучается.
#602 #436827
>>436825
потому что ты написал: выводить пуск когда i=1. А у тебя там i после цикла равняется 0.
#603 #436828
>>436827
Как оно может равняться нулю, ведь когда 1=1 то цикл должен завершиться.
#604 #436829
Можешь просто сделать мне так как надо и я перейду к след задачке.
#605 #436830
>>436828
на самом деле нет.

от сюда -> http://php.net/manual/ru/control-structures.for.php

>В начале каждой итерации оценивается выражение expr2. Если оно принимает значение TRUE, то цикл продолжается, и вложенные операторы будут выполнены.

#606 #436833
>>436828
После того как запостишь код на идеоне. Больше не меняй ни чего в нём по этому адресу. А создавай новый.
#607 #436834
>>436830
То есть цикл закончиться, не когда он должен закончиться, а когда он сломается/не сможет быть выполнен?
#608 #436839
>>436834

>То есть цикл закончиться, не когда он должен закончиться, а когда он сломается/не сможет быть выполнен?



Нет, это я на секунду затупил. Цикл не начинается если условие не выполнилось.

У тебя тут в выражении for ($i = 10; $i >= 1; $i--)

выполняется последний раз когда i = 1, но после проверки условия, идёт выражение $i--
i становится равна 0 и цикл идёт дальше.
#609 #436846
http://ideone.com/mjjOme
Жду подсказки друг.
#610 #436852
>>436846
http://ideone.com/XlltxP
Осталось решить проблему с 11 месяцем, чтобы он был двенадцатым. Но как?
#611 #436853
>>436846
У тебя в последнем месяце. Выплата идёт дважды. Это противоречит условию, выплата делается каждый месяц единожды.

Сделай так.
Сначала, Анон проверяет сколько ему осталось платить.
Если долг больше 5000, то пусть платит ровно 5000.
Если долг меньше 5000, то гасит весь долг. Выбирает что то одно, а не всё сразу.
105 Кб, 1277x658
#612 #436858
http://ideone.com/pey3lT
Так делать нехорошо же? Или типо сойдет?
#613 #436860
>>436825

У тебя ошибка в коде

> \tif($i == 1);


> }


if надо писать в в виде

if (..) {
...
}

А ты не поставил тело if (то что в фигуных скобках).
#614 #436862
>>436828

Цитккл завершается когда нарушено условие цикла то есть $i >= 1. При i = 1 он еще продолжается, при i = 0 завершается.
#615 #436864
>>436829

Сделай без if тогда. Или с if, но правильно.

>>436846

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

Смотри, у тебя в последний месяц анон платит 5000, и сразу же выплачивает 4139 остатка. А ведь он не может сразу это выплатить, он должен подождать месяц, за который набегут проценты и комиссии и итоговая сумма выйдет больше — не 49139, а около 61270.

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

Надо смотреть чему равен остаток долга и обрабатывать ситуацию, когда она маленький, а не выплачивать сразу же 5000 вот в этом месте: ... + $servicePayment - $monthlyPayment;

Попробуй переписать код внутри цикла примерно так:

- прибавляем проценты и комиссию к остатку долга
- если остаток маленький, выплачиваем сколько осталось и уходим
- иначе платим 5000

Это сложная задача, на ней все спотыкаются.
#615 #436864
>>436829

Сделай без if тогда. Или с if, но правильно.

>>436846

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

Смотри, у тебя в последний месяц анон платит 5000, и сразу же выплачивает 4139 остатка. А ведь он не может сразу это выплатить, он должен подождать месяц, за который набегут проценты и комиссии и итоговая сумма выйдет больше — не 49139, а около 61270.

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

Надо смотреть чему равен остаток долга и обрабатывать ситуацию, когда она маленький, а не выплачивать сразу же 5000 вот в этом месте: ... + $servicePayment - $monthlyPayment;

Попробуй переписать код внутри цикла примерно так:

- прибавляем проценты и комиссию к остатку долга
- если остаток маленький, выплачиваем сколько осталось и уходим
- иначе платим 5000

Это сложная задача, на ней все спотыкаются.
#616 #436865
>>436852
Да, не хорошо.
И к тому же, выплата всё равно происходит в 11 месяце, хоть ты и написал, что прошло 12 месяцев.
Я ж говорю. После выплаты 5000, на счету осталось 4138. Должен пройти ещё месяц(цикл). Должны быть на эти 4138 начислены проценты. И вот уже , когда мама Анону даст ещё 5000, он пойдёт гасить долг.

Я не ОП, могу не очень понятно обьяснять. Переспроси если что.
#618 #436867
>>436864

> и итоговая сумма выйдет больше — не 49139, а около 61270.


Исправлюясь: и итоговая сумма выйдет больше — не 59139, а около 61270.

>>436852

11-й месяц не может стать 12-м.

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

>>436858

Так делать неправильно, потому что если мы поменяем сумму кредита например на 4000 или 1000, то число 12 не поменяется.
#619 #436868
>>436866

Так правильно
#620 #436871
>>436865
этот ответ сюда писал
>>436858
#621 #436873
В задача про кредит ответ такой:

если кредит 40 000 всего вылачено 61270
если 4000 то всего выплачено 6123
если 1000 то всего выплачено 2030

Проверь что ответ совпадает.
#622 #436884
Мне похоже надо с самого начала решать первые задачки, так как я плохо понял {}if elseif () или почитать что то другое с сильной базой.
#623 #436891
>>436873
непонял тебя
#624 #436895
Если я пропущу эту задачку, то это очень плохо будет?
#625 #436896
>>436895
Какую?
#626 #436898
>>436896
W5.1 Исправь и переделай программу, чтобы она работала нормально. Например, эта версия позволяет школьнику переплатить за кредит, так, что банк ему становится должен — это плохо!
#627 #436899
>>436898
Что не получается? Код скидывай.
#628 #436907
>>436899
http://ideone.com/pey3lT

>>>11 месяц спустя


>>>11 месяц спустя

#629 #436924
>>436907
Вот сделал, маленькую переделку.

http://ideone.com/UO6CZS

Дальше сам. Доделывай
#630 #436930
>>436924
А что там доделывать? Вроде все сделал ты.
#631 #436931
>>436930
нет не всё.
при выполнении условия $creditBalance < 5000. Там проценты не начисляются.
#632 #436942
>>434648
ОП, с твоею помощью добрался до файлообменика.

https://github.com/tokotun/uppy

Глянь на набросок беглым взглядом, верной ли дорогой иду?
#633 #436944
Ух ты, читаю тред, а тут сплошное дружелюбие и желание помочь друг другу. И почти нету ни срачей, ни оскорблений. Прям и не знаю, как этого добились, но это круто!

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

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

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

В общем, жду ваших ответов
38 Кб, 535x291
40 Кб, 544x265
#634 #437060
Почему оператор XOR на php выдает не то число, которое должно быть?
Переписываю одну небольшую функцию с джавы на php, и не могу понять почему так получается.
В php я совсем ньюфаг, плиз хелп.
#635 #437065
>>437060

В java long это 64битный тип.

В php integer может быть 32- или 64- битным на рахных платформах. запусти свой код в 64 битной ОС и получишь то же самое.

int32 может быть только от -2 млрд до + 2 млрд, а у тебя 5 млрд.
#636 #437066
>>437060

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

http://php.net/manual/ru/book.gmp.php
#637 #437067
>>437065
Спасибо, теперь понятно. А можно как-то указать в php что число 5265657653 не integer, а float например?
Или единственный вариант использовать библиотеку gmp для этого?
#638 #437068
>>437067
Хотя нет, оператор XOR не работает с типом данных float.
#639 #437072
>>437067

xor принудительно преобразует float к int. Да и float неточный тип, он может не сохранить часть цифр. Используй gmp.
#640 #437134
Котаны, вот 1 анон мне задал задачу. Спарсить например с /b сосача 10 ОП-постов и сложить в базу. Начал я значит осваивать http://simplehtmldom.sourceforge.net/manual.htm
Первый шаг по получению html с помощью url все получается норм. Но вот дальше я не могу разобраться в том как управлять этой библиотекой.

Например есть общий для всех тредов контейнер:
<form id="posts form">
Как мне выпарсить только содержимое этой формы?
Как потом пройтись по её содержимому в виде:
<div id="" class="thread"> и далее к оп-постам?

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

Есть язык Xpath на котором пишутся условия для поиска узлов в xml-дереве (ну у нас HTML, в не XML, но суть та же). Ну например, «найди мне узел с определенным классом внутри которого есть минимум 2 элемента div».

https://ru.wikipedia.org/wiki/XPath
http://www.zvon.org/xxl/XPathTutorial/General_rus/examples.html
#642 #437138
>>437134

Ой, это я тебе про SimpleXML написал. Что касается SimpleHTMLDom там все понятно из примеров если ты знаешь CSS селекторы и работал с jQuery.
#643 #437139
Чем отличается
$a = 1
и
define("a",1)
и то и то присвает значение.
#644 #437141
>>437139

Первое создает переменную ( http://php.net/manual/ru/language.variables.basics.php ), второе константу ( http://php.net/manual/ru/language.constants.php ). Кстати, имена констант принято писать большими буквами.
34 Кб, 369x360
32 Кб, 373x389
#645 #437157
>>437072
В общем прикрутил gmp. Теперь при превышении значения integer, выдает ошибку что не может сконвертировать в переменную в GMP и выдает первую переменную в результате. А если вторая переменная не превышает максимальное значение integer, то вычилсяет нормально. Как добиться того, чтобы GMP понимал значения больше чем максимальное значение integer?
#646 #437168
>>437141
То есть переменную еще можно поменять, а константу нет?
Например:
define("B",1)
$b = 3
То константа не измениться. Или это совершенное разное?
#647 #437169
>>437157
Проблема решена. Надо было вместо $b = gmp_init(5265657653);
написать $b = gmp_init("5265657653", 0);
#648 #437174
>>437072
А в gmp есть фунция сдвига битов влево? Посмотрел тут http://php.net/manual/ru/ref.gmp.php , что-то не могу найти.
#649 #437246
>>437168
Вопрос актуален.
#650 #437248
Сегодня уже с утра с перерывами слушаю курс ПХП с нуля до гуру от Михаила Русакова, хоть у него и плохие комментарии, но он норм так все разжевывает, вроде немного легче понятно, чем в ссылке оппоста, хотя может и ошибаюсь.
#651 #437271
>>436944
Бббамп!
#652 #437272
>>437168

Совешенно разное.

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

>>437174

Умножить на 2 в степени N не вариант?

>>437248

Если тебе это помогает, конечно слушай.
#653 #437275
>>436944

> а почему, собственно, PHP для сайтиков?


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

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



Можно php, но если нужно максимальное бытродейтсвие то нужен java/си++ (например на асинхронных сокетах). Для крупных игр используют именно масштабируемые решения на си++ или java чтобы выжать максимум из железа.

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

> А в идеале - чтобы еще можно было к этому делу как-то прикрутить уже написанного бота


Бот может слать запросы на сервер, в чем проблема?
#654 #437280
>>436944

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


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

На сервере есть 2 модели:

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

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

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

Также, если ты держишь данные в памяти, тебе придется самому решать проблему их сохранения на диск (персистенстности). Ребята из ВК тут разобрали возможные подходы: https://github.com/vk-com/kphp-kdb/blob/master/docs/ru/DBMS_Storage_Comparison.wiki

При использовании хранилища проблему соханения решать не надо.

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

В общем что тебе стоит изучить, так это работу с сокетами, асинхронную работу с сокетами, протокол HTTP, хранилища вроде MySQl/Redis — это если ты хочешь делать по сложному варианту. На php можно сделать по простому, но с оганичением по нагрузке и без вебсокетов.
#655 #437282
>>436891

Если в задачу подставить сумму кредита 40 000 (которая там стоит по умолчанию), то должно получится что всего выплачено 61270.

Если подставить сумму кредита 4000 то должно получитьься что всего выплачено 6123.

И тд.

Если у тебя получаются другие числа то где-то неправильно считает.

>>436884

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

>>436895

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

>>436907

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

>>436930

Ответ должен быть 61270 а не 59 000
#655 #437282
>>436891

Если в задачу подставить сумму кредита 40 000 (которая там стоит по умолчанию), то должно получится что всего выплачено 61270.

Если подставить сумму кредита 4000 то должно получитьься что всего выплачено 6123.

И тд.

Если у тебя получаются другие числа то где-то неправильно считает.

>>436884

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

>>436895

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

>>436907

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

>>436930

Ответ должен быть 61270 а не 59 000
#656 #437285
>>436942

Советы и замечания

Где sql дамп базы данных?

> "twig/twig": "1.18


Лучше наверно так жестко к версии не привязываться, а написать ~1.18 например (это значит любая между 1.18 и 2.0)

Да и зачем @dev указывать? Это же нестабильная версия, с которой работают разработчики.

> $app->get('/', function () {


> require "uppy/upload.php";


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

> x.twig


Лучше назвать templates

> base.html


Лучше base.twig или base.html.twig

> <div style="margin:0;padding:0;display:inline">


Не пиши стили в style, используй классы. Чтобы скрыть блок, используй display none

> id="search"


Если ты не собирешься обращаться к элементу из JS лучше не ставь id. Он неудобен тем что не может повторяться. Для CSS удобнее использовать только классы и никогда не использовать id.

> http://localhost/uppy/upload


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

> $loader = new Twig_Loader_Filesystem('uppy/x.twig');


Это надо интегрировать в Slim чтобы при вызове слимовского $app->render вызывался Twig. Как это сделать? Надо создать слимовский вью использующий твиг и задать чтобы он использовался по умолчанию. Это можно нагуглить. Есть документация: http://docs.slimframework.com/#Custom-Views

Более того, есть уже готовая библиотека интегирующая twig в slim таким образом.

> // Try to delete the temporary file


Не надо удалять временный файл, созданный php, он сам удаляется если его не переместили.

> https://github.com/tokotun/uppy/blob/master/uppy/app/File.php#L17


> if (isset($_FILES['file'])) {


Это ужасно. С какой стати объект File, представляющий собой информацию о файле, лезет в глобальный массив FILES при создании, причем это никак не отключить? C какой стати в нем жестко захардкодено имя file? Что мне делать если у меня файл в с другими именем?

Класс File занимается не своим делом. Он не должен сам в себя прописывать свойства из FILES. должна быть какая-то внешняя функция которая берет на вход FILES и создает File.

> $numChars = strlen($chars);


Понятно что там латинница. но почему бы не использовать mb_strlen всегда?

> https://github.com/tokotun/uppy/blob/master/uppy/app/FileMapper.php#L36


> public function loadFile($key)


У нас же есть замечательный класс File, почему эта функция возвращает какой-то безликий массив?

> appvars.php


> connectvars.php


Что-то многовато конфигов. Сделай один конфиг, и без констант. желательно использовать для хранения конфига возможности Слим: http://docs.slimframework.com/#Configuration-Overview

> bootstrap.php


Код отсюда надо перенести в index.php так как у нас не будет других точек входа. получение $db надо сделать через Slim Sinleton: http://docs.slimframework.com/#DI-Overview

> https://github.com/tokotun/uppy/blob/master/uppy/app/autoloader.php


Убери этот файл и используй автозагузку средствами композера. Это описано тут например:

https://getcomposer.org/doc/04-schema.md#autoload (англ )
http://habrahabr.ru/post/149678/

Заметь что если ты используешь для именования классов и файлов стандарт PSR-0 или PSR-4 то добавление автозаргрузки делается одной строчкой в composer.json (видишь как полезно следовать стандартам). Описание стандартов есть тут

http://www.php-fig.org/psr/psr-0/ru/
http://www.php-fig.org/psr/psr-4/ru/

(там немного едет верстка, если что есть еще копия на гитхабе https://github.com/php-fig/fig-standards/tree/master/accepted )

Научись использовать автозагрузку композером и никогда больше не пиши свой автозагрузчик.
#656 #437285
>>436942

Советы и замечания

Где sql дамп базы данных?

> "twig/twig": "1.18


Лучше наверно так жестко к версии не привязываться, а написать ~1.18 например (это значит любая между 1.18 и 2.0)

Да и зачем @dev указывать? Это же нестабильная версия, с которой работают разработчики.

> $app->get('/', function () {


> require "uppy/upload.php";


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

> x.twig


Лучше назвать templates

> base.html


Лучше base.twig или base.html.twig

> <div style="margin:0;padding:0;display:inline">


Не пиши стили в style, используй классы. Чтобы скрыть блок, используй display none

> id="search"


Если ты не собирешься обращаться к элементу из JS лучше не ставь id. Он неудобен тем что не может повторяться. Для CSS удобнее использовать только классы и никогда не использовать id.

> http://localhost/uppy/upload


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

> $loader = new Twig_Loader_Filesystem('uppy/x.twig');


Это надо интегрировать в Slim чтобы при вызове слимовского $app->render вызывался Twig. Как это сделать? Надо создать слимовский вью использующий твиг и задать чтобы он использовался по умолчанию. Это можно нагуглить. Есть документация: http://docs.slimframework.com/#Custom-Views

Более того, есть уже готовая библиотека интегирующая twig в slim таким образом.

> // Try to delete the temporary file


Не надо удалять временный файл, созданный php, он сам удаляется если его не переместили.

> https://github.com/tokotun/uppy/blob/master/uppy/app/File.php#L17


> if (isset($_FILES['file'])) {


Это ужасно. С какой стати объект File, представляющий собой информацию о файле, лезет в глобальный массив FILES при создании, причем это никак не отключить? C какой стати в нем жестко захардкодено имя file? Что мне делать если у меня файл в с другими именем?

Класс File занимается не своим делом. Он не должен сам в себя прописывать свойства из FILES. должна быть какая-то внешняя функция которая берет на вход FILES и создает File.

> $numChars = strlen($chars);


Понятно что там латинница. но почему бы не использовать mb_strlen всегда?

> https://github.com/tokotun/uppy/blob/master/uppy/app/FileMapper.php#L36


> public function loadFile($key)


У нас же есть замечательный класс File, почему эта функция возвращает какой-то безликий массив?

> appvars.php


> connectvars.php


Что-то многовато конфигов. Сделай один конфиг, и без констант. желательно использовать для хранения конфига возможности Слим: http://docs.slimframework.com/#Configuration-Overview

> bootstrap.php


Код отсюда надо перенести в index.php так как у нас не будет других точек входа. получение $db надо сделать через Slim Sinleton: http://docs.slimframework.com/#DI-Overview

> https://github.com/tokotun/uppy/blob/master/uppy/app/autoloader.php


Убери этот файл и используй автозагузку средствами композера. Это описано тут например:

https://getcomposer.org/doc/04-schema.md#autoload (англ )
http://habrahabr.ru/post/149678/

Заметь что если ты используешь для именования классов и файлов стандарт PSR-0 или PSR-4 то добавление автозаргрузки делается одной строчкой в composer.json (видишь как полезно следовать стандартам). Описание стандартов есть тут

http://www.php-fig.org/psr/psr-0/ru/
http://www.php-fig.org/psr/psr-4/ru/

(там немного едет верстка, если что есть еще копия на гитхабе https://github.com/php-fig/fig-standards/tree/master/accepted )

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

У меня короче php не интерпретируется и выводится валом прямо на страницу. libphpтратата подключено, php стоит и сопутствующие библиотеки, ubuntu.

Чому?
#658 #437287
>>436942

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

> https://github.com/tokotun/uppy/tree/master/uppy/container


Это надо удалить из репозитория, закоммитить, а потом добавить содержимое папки в gitignore
#659 #437289
>>437134

> Как мне выпарсить только содержимое этой формы?


> Как потом пройтись по её содержимому в виде:


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

> а там дамп такой, что крашит мой браузер.


Посмотри может там есть встроенная функция для дампа. Или можно выводить какой-нибудь innerHTML.

>>437168

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

При этом константа A и переменная $A разные вещи.

>>437157

Потому что если ты пишешь число больше 2 млрд то оно становится float, и при этом теряется часть знаков. Потому gmp отказывается его принимать. Передавай как строку.
#660 #437290
>>437286
Причем исходный код отображается не с самого начала, а спустя какое-то количество символов. Довольно странно
#661 #437291
>>437286

Плохо подлючено. Вообще, если в Убунте ставить php стандартными средствами (apt-get install ) то он не только установит php но и в папку /etc/apache2/conf.d/ закинет файлик который подключает php к Апачу для обработки своих файлов.

Ты как ставил, чем?

Также, вопрос 2: ты в коде не забыл поставить <?php в начале?
#662 #437292
>>437286

Вопрос 3: что менял руками в конфигурации Apache или php (то есть из /etc/apache2/ и /etc/php5/)?
#663 #437310
http://ideone.com/RCP9s9
Что не так?
Задачка про вклад в банк.
#664 #437313
>>437310
Отмена, не смотрите, я исправил уже случайно.
28 Кб, 754x545
#665 #437323
>>437291
Ставил штатно, все файлики закинулы, вот папка mods-available.

>>437292
Руками? Хм. Включил работу .htaccess, прописал свою папку для файлов сайта, да и все.
#666 #437325
>>437275

>Для крупных игр


Но это не про меня, лол

>Бот может слать запросы на сервер, в чем проблема?


Да ни в чем кроме того, что я вообще не понимаю, как все это должно быть устроено
>>437280

>нужна маленькая задежрка


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

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

То есть, в принципе, для достижения моей цели достаточно просто покурить php + основы js+html, всяких навороченных штук и не надо, так?
Тогда спасибо большое за ответики, буду постепенно вливаться в ваш дружелюбный тред
#667 #437327
http://ideone.com/RCP9s9
Решите пожалуйста полностью за меня, а я сам посмотрю как это должно быть.
22 Кб, 531x378
#668 #437328
>>437323
А еще если исходный код страницы посмотреть, то часть кода как будто php, а часть - черная, как текст. Граница не ясна, на скриншоте есть.

Сейчас с теми же настройками запустил другой проект, все хорошо работает, только здесь какая-то ерунда - не полностью интерпретируется php.
#669 #437366
>>437272

>Умножить на 2 в степени N не вариант?


Что-то не могу понять что нужно умножать на 2 в степени N?
Допустим есть 5719407308<<12 на джаве.
Получается надо записать как 5719407308*212 на PHP?
#670 #437372
>>437328

Может быть в htaccess что-то прописано что отключает php? Если на этом же компютере другой проект работает?

И еще раз спрошу, там <?php в начале стоит? Или может <?

То, что раскрашено на скриншоте нважно так как это лишь браузер пытается php как html раскрасить.
#671 #437378
>>431924
Котаны, пытаюсь в данный момент на сайте реализовать примитивную систему общения. Суть заключается в том что есть Админ и он может присылать всем сообщения, причём есть возможность отсылать одно сообщение сразу нескольким людям. Я предполагаю что каждое сообщение надо записывать в базу данных, где в особенном поле должно храниться id того кому это сообщение предназначено (по которому оно будет выводиться в аккаунте у того, кому оно предназначено). Но если есть надобность отправить например 5 или больше людям одно и тоже сообщение, как лучше поступить? Записать 5 одинаковых сообщений в базу данных но с разными id для каждого пользователя? Или вписать в одно поле все id тех пользователей (через запятую) кому предназначено сообщение. В первом случае засоряем таблицу базы данных, во втором делаем много проблем себе для организации правильного вывода сообщений в аккаунте у тех кому они предназначены. Или может куда более лучший третий вариант?
#672 #437387
>>437372
.htaccess скопирован с другого сервера, где изначально крутился этот проект, так что вряд ли там ошибка. В начале не было php, только <?. Добавил, перезапустил - выводимый код немного изменился, но суть осталась той же - не обрабатывает. Хотя появилась среди строк голой выдачи какая-то ошибка:
Problem encountered: $error.

Недоинтерпретированный кусок.
#673 #437502
Есть кто?
#674 #437503
Зачем стер?
#675 #437506
http://ideone.com/LNdlms
Направьте на путь истинный.
#676 #437509
>>437506
Ты каждую итерацию цикла пишешь в $dohod одно и то же число, а тебе надо прибавлять к тому что уже есть
#677 #437511
>>437509
Я сам по результатам это вижу, но незнаю что изменить.
#678 #437513
сам несмогу нужна помощь
#679 #437514
>>437511
Переменная $dohod должна присутствовать и в левой и в правой части уравнения.
#680 #437516
>>437511

>надо прибавлять к тому что уже есть

#682 #437520
http://ideone.com/tsdARX
Чё он не жирный?
#683 #437527
>>437387

<? по умолчанию отключен. Надо всегда использовать <?php

В твоем случае надо либо включить short_tags либо, что правильнее, всюду поменять <? на <?php

Мануал http://php.net/manual/ru/language.basic-syntax.phptags.php

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


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

>>437378

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

>>437506

> $dohod = ($vklad * $procent) + $vklad;


Это примерно то же самое что

$dohod = 11000;

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

$dohod = $dohod + 10;

(или что то же самое , $dohod += 10; )

Это увеличивает число в переменной на 10.

Ну и поменяй русские имена на английские, если не знаешь английский то можешь использовать google translate или slovari.yandex.ru .По руссски не принято переменныенаывать.
#683 #437527
>>437387

<? по умолчанию отключен. Надо всегда использовать <?php

В твоем случае надо либо включить short_tags либо, что правильнее, всюду поменять <? на <?php

Мануал http://php.net/manual/ru/language.basic-syntax.phptags.php

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


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

>>437378

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

>>437506

> $dohod = ($vklad * $procent) + $vklad;


Это примерно то же самое что

$dohod = 11000;

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

$dohod = $dohod + 10;

(или что то же самое , $dohod += 10; )

Это увеличивает число в переменной на 10.

Ну и поменяй русские имена на английские, если не знаешь английский то можешь использовать google translate или slovari.yandex.ru .По руссски не принято переменныенаывать.
#684 #437528
>>437517

Тут есть ошибки:

> $dohod = (($vklad * $procent) + $vklad + $dohod);


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

>if ($dohod = 1000000) {


Неправильно. Для сравнения надо писать $dohod == 100000. В if всегда надо использовать ==.

= обозначает не сравнение, а присваивание, то есть присвоить $dohod значение 1000000.

Ну и имена хорошо бы на английские поменять.

>>437520

Он и не должен быть жирным. ideone не интерпретирует html код как браузер, а просто выводит как есть. То же самое будет если ты запустишь программу например в консоли. Теги работают только в браузере.
#685 #437548
>>437528

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


Надбавка каждый год будет увеличиваться, так как сумма на счету тоже каждый год увеличивается. Я низнаю.
#686 #437560
http://ideone.com/fdce4f
Помогите плиз.
#687 #437597
>>437548
>>437560

надбавка = сумма на счете × процент;
прибавляем надбавку к сумме на счете;

Вот это практически готовое решение, надо его только в виде кода записать.
#688 #437603
http://ideone.com/VFVN3M
Я всё правильно сделал, или можно было проще?
#689 #437607
>>437603

Все правильно сделал.
#690 #437611
>>437607
Спасибо ^^
#691 #437613
>>437560
Если я все правильно понял, то вот:

http://ideone.com/VdRFQV
#692 #437614
>>437613

Только надо миллион накопить, а не 100 000. Но идея правильная.

И еще,

$a = $a × $b;

можно записать короче как

$a ×= $b;
19 Кб, 400x266
#693 #437637
Сап, Phpач. Теперь задача на функции и айпад в кредит.
Вроде бы и всё понимаю, но пока не получается. Мне "стоп" нужно заключить в функцию, или прописывать отдельно после нее?
Вот то что нашкрябал. Пока до отрицательных значений долга не доходишь вроде как пашет.
#694 #437639
>>437637
http://ideone.com/QUP4Kc
А код та забыл.
#695 #437721
http://ideone.com/kJdUp9
Первую задачку с массивами сделал за 5 минут. А еботня с циклами и кредитами так и не закончилась.
#696 #437749
>>437721
Хочу удостовериться, правильно сделано?
#697 #437755
Котаны, поясните по поводу авторизации. Вот например есть форма, я принимаю из ней данные, обрабатываю в функции, нахожу что такой пароль и логин есть в базе данных.

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

Форму у меня обрабатывает та же страница на которой она и находиться, вероятно именно в этом моменте я чего то не пойму.
#698 #437756
>>437755

редирект?
#699 #437758
Бля как же это хуево, когда есть желание выучить пхп, но ты ПРОСТО НЕПОНИМАЕШЬ, как решить задачку.
Вот пытаюсь сделать "Еще одна задачка. Дан рост школьника и рост его одноклассников. Надо найти, сколько человек в классе выше, чем наш герой."
#700 #437776
>>437758

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

>>437721

Все правильно

>>437639

> Мне "стоп" нужно заключить в функцию, или прописывать отдельно после нее?


Не понял вопрос. Что за стоп?

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

Код по моему у тебя не дописан, обрывается на полуслове.
#701 #437777
>>437756
Не знаю как это правильно называется, но я использую:

Header("Location: catalog.php");

В том случае если правильно введены все данные
#702 #437782
>>437527

>Можно сделать таблицу сообщений и связь многие-ко-многие между сообщениями и пользователями.


Но в любом случае, одно и тоже сообщения но только предназначенное для двух разных пользователей, будет занимать две строки в таблице, правильно?
#703 #437786
>>437776

>>>затем проходишь по списку одноклассников


Использовать перебор массивов foreach?
#704 #437796
Аноны, я спать.

>>437777

Это и есть редирект

Добавляй туда нужный id в url

>>437782

Текст сообщения будет один. А 2 строки будут только в таблице связи.

>>437786

Да, он подойдет
#705 #437892
Товарищи, нужен совет.
Провожу по работе часов 6 в день в дороге, хочу годную среду разработки под ведроид, а то постоянно по возвращении домой забиваю на обучение и в итоге даже стартовые задачи еще не сделал.
Короче посоветуйте под чем кодить на планшете, пожалуйста.
#706 #437901
46 Кб, 927x642
#707 #437906
Ребят, у меня тут верстается страница, по центру колона в которую будет выкладываться видео , под ним поле для комментов. пикрелейтед.
посоветуйте как лучше сверстать этот блок с видео, может есть шаблон который можно допилить? спасибо
47 Кб, 1334x628
#708 #437908
Ребят, у меня тут верстается страница, по центру колонка в которую будет выкладываться видео , под ним поле для комментов. пикрелейтед.
посоветуйте как лучше сверстать этот блок с видео, может есть шаблон который можно допилить? спасибо
#709 #437913
http://jsfiddle.net/2wmrmpek/1/ Исправил вторую задачу. Теперь вроде окончательно.
#710 #437938
>>437906
Не совсем понял, что там верстать-то?
#711 #437959
>>433153

> http://php.net/manual/ru/language.oop5.overloading.php#object.get



Это аналог рубийного attr_accessor ?
#712 #437994
>>437776
Стоп всмыле не переплачивать за кредит.
Во всём остальном я разберусь.
Спасибо.
#713 #438031
http://jsfiddle.net/6bauqm0e/ 4ая задача. Сначала сделал без отступов, с полями, потом обнаружил, что последний блок не на одной линии должен находиться, с первыми двумя, пришлось добавлять маржинов. Я, наверное, не правильно решил.
46 Кб, 732x320
#715 #438042
В чем может быть проблема?
Когда добавляю group строка перестаёт вставляться в таблицу, без group всё работает?
#716 #438044
Аноны, тут когда-то всплывала ссылка на вероятные вопросы которые бывают на собеседованиях, можете поделиться если не тяжело.
#717 #438052
>>438042

Какое сообщение об ошибке? Если сообщения нет то это значит что включен режим игнорирования ошибок от базы данных.

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

$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

Мануал: http://php.net/manual/ru/pdo.error-handling.php

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

$pdo->exec("SDASDASDASDASDA");

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

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

- ошибки сохраняются в лог ошибок. Можно открыть его и почитать. Если ты запускаешь код на локалхосте, у себя, то лог хранится в папке Апача (обычно она называется logs) и имеет название вроде error.log (в линуксе в папку /var/log/apache2 ). Если на хостинге — там либо есть файл error.log либо раздел в панели управления, где лог можно посмотреть

- также, ты можешь включить отображение ошибок. Открой файл php.ini, поставь там display_errors = On и error_reporting = E_ALL и перезапусти сервер. Теперь ошибки должны выводиться на экран.

Проверить, работает ли вывод ошибок, можно запустив скрипт содержающий обращение к несуществующей переменной вроде echo $sdgasdad; и проверив, выведется ошибка или нет. Если все верно, то должна вывестись.
#718 #438064
>>437892

Под андроид есть редакторы кода и есть возможность запускать PHP. Весь наш учебник можно прорешать на нем (а также дополнительные задачи на создание сайтов). Чтобы решать задачи, тебе нужно несколько вещей:

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

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

Если искать по словам PHP IDE то вываливаются в основном платные IDE. Но там все уже идет в комплекте + есть например тот же MySQL.

Но можно и ставить по отдельности. Вот например что гуглится:

- http://droidphp.github.io/ (бесплатный сервер, включает php и mysql)
- https://play.google.com/store/apps/details?id=com.esminis.server.php (MySQL нету)
- https://play.google.com/store/apps/details?id=com.ayansoft.androphp
- https://play.google.com/store/apps/details?id=com.alfanla.android.pws

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

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

Также я советую скачать мануал по PHP: http://php.net/download-docs.php если тебе неудобно пользоваться мануалом через интернет.

Он доступен либо в виде CHM файла (и для его просмотра наверно нужно приложение) либо в виде архива HTML файлов которые непонятно как просматривать на устройстве.

>>437901

AIDE для Java и С++ как следует из описания
#718 #438064
>>437892

Под андроид есть редакторы кода и есть возможность запускать PHP. Весь наш учебник можно прорешать на нем (а также дополнительные задачи на создание сайтов). Чтобы решать задачи, тебе нужно несколько вещей:

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

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

Если искать по словам PHP IDE то вываливаются в основном платные IDE. Но там все уже идет в комплекте + есть например тот же MySQL.

Но можно и ставить по отдельности. Вот например что гуглится:

- http://droidphp.github.io/ (бесплатный сервер, включает php и mysql)
- https://play.google.com/store/apps/details?id=com.esminis.server.php (MySQL нету)
- https://play.google.com/store/apps/details?id=com.ayansoft.androphp
- https://play.google.com/store/apps/details?id=com.alfanla.android.pws

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

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

Также я советую скачать мануал по PHP: http://php.net/download-docs.php если тебе неудобно пользоваться мануалом через интернет.

Он доступен либо в виде CHM файла (и для его просмотра наверно нужно приложение) либо в виде архива HTML файлов которые непонятно как просматривать на устройстве.

>>437901

AIDE для Java и С++ как следует из описания
#719 #438066
>>438052
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'group) VALUES ('23', '23', '23', '23')' at line 1' in Z:\home\test.ru\www\testsql\lib\pdo.php:71 Stack trace: #0 Z:\home\test.ru\www\testsql\lib\pdo.php(71): PDOStatement->execute() #1 Z:\home\test.ru\www\testsql\index.php(19): DataMapper->addStudent(Object(Profile)) #2 {main} thrown in Z:\home\test.ru\www\testsql\lib\pdo.php on line 71

Синтаксическая, но я не понимаю что не так.
Ведь когда три параметра всё норм.
#720 #438068
>>437906

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

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

>>437913

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

>>437959

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

>>437994

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

- прибавляем проценты и комиссию к остатку долга
- если остаток маленький, выплачиваем сколько осталось и уходим
- иначе платим 5000

>>438031

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

> \tmargin-bottom: 6px;


Это у меня косяк, картинка криво нарисована. На самом делел 3-й блок выровнен нижним краем с первым блоком о высоте.

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


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

> Сначала сделал без отступов, с полями


Так и надо было

По горизонтали у тебя не 10px, вот я даже квадратик нарисовал для сравнения: https://jsfiddle.net/kejsdrfe/1/

Посмотри подсказки к заданию, там есть полезная ссылка на тему почему там не 10px получается.
#720 #438068
>>437906

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

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

>>437913

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

>>437959

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

>>437994

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

- прибавляем проценты и комиссию к остатку долга
- если остаток маленький, выплачиваем сколько осталось и уходим
- иначе платим 5000

>>438031

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

> \tmargin-bottom: 6px;


Это у меня косяк, картинка криво нарисована. На самом делел 3-й блок выровнен нижним краем с первым блоком о высоте.

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


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

> Сначала сделал без отступов, с полями


Так и надо было

По горизонтали у тебя не 10px, вот я даже квадратик нарисовал для сравнения: https://jsfiddle.net/kejsdrfe/1/

Посмотри подсказки к заданию, там есть полезная ссылка на тему почему там не 10px получается.
#721 #438070
>>438037

Тут все верно. Главная цель этой задачи понять как работает padding на inline элементах.

>>438044

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

>>438042

GROUP это зарезервированное слово (там есть опция GROUP BY)/ . Надо писать его в косых кавычках, аналогично с другими резервированными словами.Вот мануал, выучи наизусть:

http://www.mysql.ru/docs/man/Reserved_words.html
http://makefuture.net/article/mysql-all-reserved-words/
http://spec-zone.ru/RU/mysql/5.7/language-structure_reserved-words.html

Ок, насчет выучить наизуcть я поушутил. Не надо учить ничего
#722 #438071
>>438066

group — зарезервированное слово
#723 #438074
>>438068

>ты используешь 2 дива, неоптимально, тут можно обойтись одним. Подумай, как


Ты имеешь ввиду -webkit-box-sizing: border-box?
#724 #438076
>>438071
спасибочки
#725 #438077
>>438042

Вот правильная ссылка про косые кавычки: http://www.mysql.ru/docs/man/Legal_names.html
#726 #438078
>>438074

Нет, я предлагаю просто вычесть из 600 паддинг и бордер и прописать как max-width.

Кстати, в новых браузерах надо писать

box-sizing: ...
-moz-box-sizing: ...
-webkit-box-sizing: ...

Вендорные рефиксы работают только в старых версиях браузеров. Сейчас они признаны дурной идеей и не исплоьзуются (но ставить их стоит для старых браузеров).
#728 #438089
>>438083
влезу в ваш диалог и предложу выставить
box-sizing: border-box
#729 #438095
>>438089

Там можно решить задачу и без него. То есть border-box это хорошо конечно, но можно просто ширину посчитать за вычетом border и padding.

>>438083

Да, верно.
#730 #438096
Переходите в новый 44-й тред: >>438085

Этот тред закрыт.
Тред утонул или удален.
Это копия, сохраненная 4 марта 2015 года.

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

Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
« /pr/В начало тредаВеб-версияНастройки
/a//b//mu//s//vg/Все доски