обсудитьВ начало раздела
Наверх
Ничего не работает! Что делать???
Введение. Очень важное.
Сообщения об ошибках PHP.
Отладка и поиск ошибок в своем алгоритме.
Пример отладки.
Самое важное - знать, что ты хочешь получить.
Заключение.
Введение. Очень важное.
Ты написал программу, а она не работает.
Вариантов ты видишь немного - либо сидеть и пытаться умственным усилием обнаружить ошибку, в сотый раз просматривая код, либо пойти на форум и попросить, чтобы там тебе нашли ошибку.
Самое интересное, что есть третий, в сто раз лучше первых двух.
Этот способ называется "Отладка программы". По-английски - debugging.
Заключается он в том, чтобы заставить программу саму показать, где в ней ошибка.
Это мало того, что получится быстрее, чем спрашивать на стороне - так зачастую это
единственный способ решить проблему. Единственный.
Я тебе сейчас открою страшный секрет. В мире НЕТ программистов, которые пишут код, как художники на Арбате - сел, наваял, отдал. Нету. И не будет.
Процесс написания программы - циклический: Написал кусок кода - посмотрел, как работает. Если не работает - ищем ошибки. Работает - пишем дальше.
Только так. Других вариантов нет.
Больше того. В большинстве случаев совершенно бесполезно вываливать на форум свой код, и спрашивать - "В чём ошибка?". На форуме не сидят волшебники вперемешку с телепатами. И гадалок с прорицателями - тоже нет. Поэтому отгадывать, в чём, теоретически, может быть ошибка, никто не будет. Ошибку найти может только хозяин программы. На своём сервере. Со своими нстройками и опечатками. Поэтому локализовать ошибку - найти мето, где она происходит, определить тип ошибки - можно только самостоятельно. А вот исправить её на форуме помогут. Если не получится самому.
Те, кто приходит к веб-программированию от дизайна, или от игр, или от нечего делать, проcто не знают этой страшной тайны: Основное время программиста уходит не на написание кода.
Основное время программиста уходит на поиск ошибок и отладку. Это не шутка. Это правда. И если вы решили заняться программированием, то вам придётся искать ошибки точно так же, как это делают все остальные.
К сожалению, очень много людей приходят к PHP вообще без опыта программирования и, как следствие - никогда не слышали об отладке.
А это и есть самое главное в программировании - умение искать ошибки.
И мы с тобой сейчас будем учиться их искать.
Программа не работает. Что можно сделать в этом случае?
Сообщения об ошибках PHP.
Самый твой большой помощник в деле отладки - это сам PHP. При возникновении любых проблем он сообщит тебе о них. То есть, в первую очередь ты должен убедиться в том, что если сообщение об ошибке есть - ты его увидишь.
Пояснение: Очень многие люди не понимают, что такое сообщение об ошибке. В основном эти люди делятся на две категории. Первая считает, что сообщения об ошщибках - это блажь разработчиков языка, надоедливый сервис, сделанный для того, чтобы программисту было не скучно. И избавляться от сообщений надо любыми доступными способами. Вторая категория не выросла из школьного возраста и воспринимает не смысл ошибки, а лишь сам факт. Принимают язык за стервозного завуча, который ругает не по делу, а абстрактно, за то, что оболтус. То есть, факт появления ошибки вызывает у этих людей только негатиные эмоции, а в смысл они даже не пытаются вчитываться.
Это чудовищные заблуждения. Сообщения об ошибках - это ПОМОЩЬ! Это громадная помощь программисту. Как ей воспользоваться, мы рассмотрим ниже.
Даже самый рабочий код, которому ты на 100% доверяешь, и который на соседней машине работает, как часы, может выдавать сообщение об ошибке. Причин тому может быть бесконечное множество. Это и такой распространенный случай, как отсутствие прав доступа к файлам, и такие экзотические, как запрещение провайдером выполнения самых распространенных и безобидных функций.
Твоя задача - обеспечить интерпретатору возможность сообщить тебе об ошибке при возникновении оной.
Ты должен быть уверен, что если выполнение программы вызывает ошибку, то ты эту ошибку увидишь.
Что интерпретатору не запрещено сообщеть тебе об ошибке.
Что ты запросил все варианты вывода сообщения об ошибке.
Во-первых, надо выяснить, выводятся ошибки на экран или пишутся в лог. Обычно, домашний, или тестовый сервер настраивается так, чтобы ошибки выводились на экран. Рабочий же сервер, с сайтом в публичном доступе ОБЯЗАТЕЛЬНО должен быть настроен так, чтобы ошибки не выводились на экран (поскольку посетителю они все равно ничего не скажут, а программист их не увидит), а писались в лог, где программист их увидит.
Если ты не уверен, и не знаешь, где посмотреть, а ошибку найти надо срочно, то напиши в самом начале скрипта две строчки
ini_set('display_errors','On');
error_reporting(E_ALL ^E_NOTICE);
Эти две строки заставят выводить сообщения обо всех критических ошибках на экран.
Если никаких ошибок не выведется, надо написать
error_reporting(E_ALL);
Это
очень сильно поможет, показав несуществующие переменные и другие мелкие ошибки, которые обычно игнорируются, но от которых может зависеть работспособность программы.
Во-вторых, убедись, что в коде отсутствуют символы '@' перед именами функций. Этот запрещает вывод сообщения об ошибке. Хорошенькое дело! Ты ошибку ищешь-ищещь, а сам же своей программе рот заткнул.
Если ты уверен, что ошибка есть, но на экран она всё равно не выводится - найди лог ошибок веб-сервера. Обычно, это файл с названием error_log. Где он находится - надо посмотреть в документации или спросить в службе поддержки провайдера.
При возниконовении проблем с функциями
mysql (supplied argument is not a valid MySQL result resource) под строкой, где произошла ошибка, обязательно надло вывести на экран
mysql_error()
и сам запрос - для визуального контроля и копирования на форум.
При работе с
изображениями, чтобы увидеть сообщение об ошибке, обязательно надо догадаться отключить вывод заголовка, говорящего браузеру, что дальше идет картинка.
При аплоаде в первую очередь смотрите массив $_FILES.
При проблемах во взаимодействии сервера и клиента - в обязательном порядке смотреть
обмен HTTP заголовками
И всегда смотрите не то, что показывает браузер, а ИСХОДНЫЙ HTML код!
Допустим, сообщение об ошибке появляется и ты его получил. Что делать дальше? Очень просто - прочесть и исправить. Если не хватает зания английского языка, то стоит либо воспользоваться переводчиком, либо взять значащую часть этого сообщения и запросить Google. 90% вероятности, что кто-то с такой ошибкой уже сталкивался и ты тут же прочтешь ответ.
Если же не нашел, то задай вопрос в форуме, точно скопировав небольшой (3-5 строк) кусок кода, в котором произошла ошибка, точно указав строку, о которой говорится в сообщении об ошибке, а так же - самое главное! - само сообщение об ошибке.
Согласись, что с такой информацией тебе на форуме помогут гораздо скорее и качественней?
Отладка и поиск ошибок в своем алгоритме.
Но бывает так, что программа не вызывает ошибок, но все равно не работает, или работает не так, как надо.
Тут уже виноват или алгоритм или какие-то внешние факторы.
Однако и тут можно найти место, где происходит ошибка.
Но только при одном условии.
что ты четко представляешь, что делает твоя программа, каждая функция, каждая строка в ней. Потому, что если ты представляешь, то можешь предсказать, какие значения должны иметь переменные на каждом этапе выполнения.
А дальше все ОЧЕНЬ просто!
Во-первых, надо разделить программу на логические блоки.
Допустим, скрипт выводит форму, получает ее, и записывает данные в базу. ТРИ шага! И в любом из них может быть ошибка, приводящая к тому, что данные в базу не записываются.
Надо проконтролировать на каждом из участков - все ли переменные имеют то значение, которое ожидается.
Программа ведь работает с переменными.
Как проверить?
Всего лишь написать в паре мест echo (для строк и чисел) и print_r() (для массивов) и выясняешь - обана! А переменная-то пустая!
И уже можешь пойти на форум не с вопросом "у меня вот код на 100 строк, где ошибка?", а "я написал функцию, но почему-то, когда обращаюсь в ней к переменным, они все пустые". или "из формы не передаются переменные".
Между этими двумя способами задания вопросов - пропасть.
Первый не может тебе помочь никак. Ты, собственно, и сам не знаешь, что у тебя за проблема. А при втором ты уже знаешь проблему, и, если сам не справился с ее решением, то можешь задать на форуме конкретный вопрос.
Еще очень поможет избежать ошибок в программе выставление error_reporting в E_ALL с самого начала работы скрипта.
Если при отлове критических ошибок сообщения о
потенциальных ошибках могут нам помешать увидеть главную, то при разработке нам желателно видеть все - и потенциальные в том числе. Скажем, при E_ALL, при обращении к несуществующей переменной, PHP выдаст предупреждение. То есть, тебе не придется самому выводить переменную, чтобы выяснить, что ты не присвоил ей никакого значения - РНР тебя сам предупредит.
Пример отладки.
Из html формы передаются чекбоксы с именами c_1, c_1, c_3... c_10
В скрипте мы пытаемся в цикле вывести
for ($i=1, $i<11, $i++) {
echo $_POST['с_$i'];
}
скрипт ничего не выводит.
Начинаем отлиаживать.
Сначала смотрим в исходный код html страницы. соответствует ли она стандартам?
Допустим, соответствует. Значит, проблема не в форме.
Далее, проверяем в скрипте - а есть ли такая переменная, к которой мы обращаемся - массив $_POST?
пишем
echo '<pre>';
var_dump($_POST);
Убеждаемся в том, что массив есть и все элементы на месте. Значит, проблема не в передаче.
Значит, мы как-то неправильно обращаемся к массиву.
обращаемся мы к нему так: $_POST['с_$i']
Надо проверить - а во что превращается 'с_$i'?
делаем echo 'с_$i'; и видим... совсем не то, что ожидали увидеть.
И вот теперь уже идем либо читать документацию про строкив пхп (что предпочтительнее), либо - на форум, с вопросом "почему у меня переменная не заместилась своим значением". Каковой вопрос будет гораздо лучше звучать, чем "у меня форма не работает".
Понятно?
Следует понимать, что здесь приведён пример, Нереальный. Показан алгоритм действий.
В реальности, при error_reporting(E_ALL); PHP сразу же показал бы, что индекс массива у вас неправильный.
Самое важное - знать, что ты хочешь получить.
Примерно половина вопросов на форумах вызвана тем, что человек делает что-то...НЕ ЗНАЯ, что именно!
Самый гениальный вопрос всех времён и народов: "у меня база съела все переводы строк из текстарии".
Человек просто не дал себе труд посмотреть, как будет выглядеть HTML, который он хочет получить, и решил, что переводы строк съела база.
И так во всём.
Непризнанный гений строит сложный SQL запрос, а когда его спрашивают, как запрос должен выглядеть - он только хлопает глазами. ВСЕГДА СНАЧАЛА составьте запрос руками и выполните в консоли или phpmyadmin! А после того, как получили нужный запрос и отладили - милости просим, составляйте его на пхп.
Работа с удалённым хостом через сокет по протоколу HTTP - то же самое! Сначала научитесь выполнять все команды руками, посмотрите ответы сервера глазами, а потом моделируйте этот диалог в пхп.
Работа с яваскриптом по тому же методу описана в факе
"на танке"
Запомните - на пхп вы работаете только со СТРОКАМИ! HTML страница, которую вы создаёте скриптом - это для пхп всего лишь набор строк! Ему без разницы, что в этом наборе - теги img, script или frame. Пхп за вас не сделает переводы строк, не нарисует яваскрипт. Если вы не знаете яваскрипта - то не пытайтесь создавать программу на нём с помощью PHP.
Осткрывая соединение с удалённым хостом, вы посылаете строку в сокет, вы получаете строку из сокета. Пхп ничего не понимает в этих строках и за вас диалог вести не будет! Это ВЫ должны чётко понимать, что вы хотите послать в сокет, и то получить! Поэтому возьмите программу telnet, соединитесь с нужным хостом и пробуйте сначала САМИ сделать то, что хотите заставить сделать пхп.
Если у вас не работает скрипт с сокетами - бегом в телнет смотреть, что происходит!
SQL запрос - это СТРОКА. Вы должны себе чётко представлять, какой запрос поулчится в результате вашего хитроумного пхп-кода! Сервер БД не понимает конструкций intval, date, mktime и так далее! Это всё пхп-код. Результатом которого будет являться строка корректного SQL запроса. прежде, чем писать пхп код, вы должны себе ЧЁТКО СЕБЕ ПРЕДСТАВЛЯТЬ, КАК ДОЛЖЕН ВЫГЛЯДЕТЬ SQL ЗАПРОС В РЕЗУЛЬТАТЕ!
Если у вас не выполняется SQL запрос 0 выводите его на экран и смотрите - что нагородили своим скриптом!
Заключение.
Отладка - главное занятие программиста.
Отладка - единственный и самый мощный способ найти ошибку в программе.
Отладка состоит из двух основных компонентов:
1. Максимально упрощать пример. Если у вас не работает программа, которая рисует форму,получает данные, записывает данные формы в базу и вывдит их снова, то разбейте программу на составляющие и выполняйте по очереди.
Если у вас не работает сложная подпрограмма определения работоспособности кук - напишите сначала тест в две строчки чтобы убедиться, что вы хотя бы можете выставлять и читать куку.
2. Вывод отладочной информации.
Проверяйте значение КАЖДОЙ переменной! Каждого значения, возвращаемого функцией!
Не работает локейшен? Выведите его на экран и скопируйте в браузер!
В файл записывается пустая строка? проверяйте составляющие этой строки на каждом этапе ее создания и выводите на экран!
Убедились, что на экран выводится? Тренируйтесь писать в файл, на
тестовой строке! Забитой прямо в скрипт! Уменьшайте количество неизвестных!
И всегда смотрите не то, что показывает браузер, а ИСХОДНЫЙ HTML код!
Надеюсь, что я смог хотя бы немного объяснить принципы этого занятия.
Удачной отладки.
В начало раздела
Наверх
Не передаются переменные! Проблема register_globals
Все нормально. Данные в скрипт передаются. Просто при определенных настройках РНР не делает из них переменные. Найти свои данные можно в специальных массивах.
Во всех старых руководствах по РНР написано, что даные, полученные из формы, или переданные по ссылке, вот так:
script.php?peremennaya=znachenie&variable=value
автоматически становятся переменными PHP,
$peremennaya
и
$variable
Эта информация устарела.
Дело в том, что в целях безопасности, начиная с версии 4.1, РНР настраивается по умолчанию так, чтобы переданные значения не назначались переменным.
Получить же переданное значение можно обратившись к соответствующему массиву.
Например:
Если передаем методом GET, обратившись к скрипту по ссылке вида
script.php?var=value
или отправив форму, указав в ней method="GET",
то все переменные содержатся в массиве
$_GET
.
echo $_GET['var']
; напечатает "
value
".
Если получаем данные из формы, отправленной методом POST, то все поля этой формы содержатся в массиве
$_POST
. Допустим, в форме был элемент
<input type="hidden" name="var" value="1">
,
то в скрипте, который указан в action формы, можно написать echo
$_POST['var'];
и будет выведена 1.
Поэтому, если вы уверены, что переменная есть, но вы не можете ее найти - ищите ее в суперглобальных массивах.
Подробнее о них можно почитать на русском языке в официальной документации
http://ru2.php.net/variables.predefined
То же касается и серверных переменных, таких, как
$REMOTE_ADDR, $PHP_SELF
. Получить их можно, обратившись к массивам
$_SERVER, $_ENV
или функцией
getenv -
getenv('HTTP_REFERER')
;
Переменные, зарегистрированные в сессии, следует искать в массиве
$_SESSION
.
Данные cookie содержатся в массиве $_COOKIE, сведения о закачанных файлах - в $_FILES
Переменные окружения - в $_ENV, а так же, существует массив $_REQUEST, в котором собраны данные из GET, POST и cookie.
Важно!
Весьма в поисках переменных помогает одна их главных функций PHP - phpinfo()
ее следует применять всякий раз, когда вы "потеряли" переменную, вызовите phpinfo(32);
в скрипте, в котором не работает авторизация, в скрипте, который принимает файл при аплоаде - и все найдется!
За назначение переменных отвечает параметр
register_globals
в php.ini.
Если
register_globals
=
on, то все полученные скриптом данные будут назначены соответствующим переменным.
Разработчики PHP настоятельно рекомендуют выключать
register_globals
(такой режим даже введен по умолчанию во всех новых версиях) и пользоваться данными, полученными от пользователя, только обращаясь к соответствуюим массивам.
Это сделано потому, что при
register_globals
=
on легко взломать небрежно написаный скрипт.
К примеру, функция авторизации выставляет переменную
$admin=1
, а если авторизации не было, то не делает ничего. В таком скрипте при
register_globals
=
on очень легко стать админом, просто обратившись к нему
script.php?admin=1
Огоромное количество сайтов было взломано таким образом.
К тому же,
register_globals
=
off заставляет пользоваться суперглобальнми массивами (
$_GET, $_POST
и т.д.), что помогает избежать путаницы. ОЧЕНЬ много людей, записав некую переменную в сессию, а потом пытаясь изменить ее значение, передавая ее скрипту методом GET, долго не могли понять, почему у них ничего не работает? Поэтому
очень важно при работе с сессиями, при любых настройках (и особенно - при
register_globals
=
on!) работать
только с массивом
$_SESSION
, как это описано в
соответствующем разделе.
То есть,
register_globals
=
off - на самом деле не цель, а средство. Побудительный мотив для программиста писать защищенные скрипты и избегать путаницы.
Если вы хотите написать скрипт, не зависящий от настройки register_globals
, и при этом защищенный - переменные надо объявлять перед использованием. На это нацелена еще одна инициатива разработчиков PHP - написание программ при уровне отображения ошибок (error_reporting) равном E_ALL, при котором об использовании необъявленных переменных выдаются предупреждения.
Именно объявление ВСЕХ переменных, используемых в скрипте и являетс гарантией от взлома. Если вы пишете программу для распространения, то гарантией ее безопасности является только объявление переменных.
Если же нет возможности переделать готовый скрипт, но его надо заставить работать при
register_globals
=
off, то надо помнить, что во-первых, вы делаете потенциальную дыру у себя на сайте, а во-вторых, для этого можно воспользоваться функциями
extract
и
import_request_variables
НО!
Бездумное использование этих функций является таким же опасным!
Если вы хотите адаптировать старый скрипт под новые правила, то выполните приведенный код именно в таком порядке!
import_request_variables("GPC");
extract($_SERVER);
сначала назначаются переменные, пришедшие от юзера, а потом - предопределенные серверные, чтобы первые не могли затереть одноименные серверные.
ВАЖНО!!!
Этот код должен вызываться как можно раньше в скрипте. ДО любого кода и присвоения переменных.
Поскольку он являет собой дыру похлеще register_globals=
on!
Ведь если он будет вызываться после присвоения переменных в скрипте, то хакер с легкостью перезапишет их.
Последние версии PHP сообщают вам об этом нотайсом при использовании import_request_variables.
И то правда - три года прошло с тех пор, как введены новые правила. Пора бы уже и научиться писать скрипты правильно.
Но лучше всего пользоваться не свалеными в кучу переменными, а соответствующими массивами. Особенно, если в одном скрипте встречаются переменные из кук, из формы, из сессии - очень много путаницы от этого происходит.
Все то же самое можно прочесть и в документации:
http://www.php.net/manual/ru/security.globals.phpВ начало раздела
Наверх
MySQL. Просто и понятно.
FAQ. Порядок записей, первая и последняя.
FAQ. ID.
Язык SQL.
FAQ. Перенос данных между разными серверами.
Практическое использование.
Базы данных, и в частности, язык SQL, и, в частности, СУБД MySQL - гениальное изобретение человечества. Это совершенно иной подход к хранению и обработке данных, чем столетиями использовавшиеся последовательные списки. Именно в подходе к хранению данных и кроется как мощь БД, так и ошибки начинающих пользователей, путающих её с привычным списком.
FAQ. Порядок записей, первая и последняя.
Список - это текстовый файл. Или, скажем, список учеников в классном журнале.
чтобы получить упорядоченный список, мы должны, при добавлении любой записи, список переупорядочивать. При добавлени любой! А если мы хотим иметь два и больше видов упорядочивания? К примеру, список учеников у нас составляется по алфавиту, но нам интересно посмотреть его по успеваемости. Заводить два списка? НЕТ! Завести базу данных.
И понять первый, самый основополагающий принцип. Порядок у данных бывает только при выборке их из БД ! Это очень важный факт. Данные в БД хранятся не как в классном журнале - по порядку. А как в песочных часах - кучей. Не задашь порядок вывода - будут выводиться от балды. Сама база не запоминает, какая запись была первой, а какая - последней. Но зато она умеет сортировать по признакам, указанным пользователем при создании таблицы.
Первое, что надо запомнить. В базе не бывает первой и последней записи. О порядке можно говорить только при выводе, если пользователь сам задал этот порядок. к примеру, отсортировав записи по алфавиту. Вот в такой выборке есть и первая и последняя.
Если нам нужно знать порядок занесения записей в базу - добавьте поле, с помощью которого это можно определить.
Следующее, чем отличается БД от файла - это произвольный доступ. В файле, для того, чтобы обратиться к строке в середине, надо перебрать по очереди все идущие до неё. При обновлении - еще хуже. Для того, чтобы изменить строчку в строковом файле - надо переписать его ВЕСЬ! Целиком. С БД же - все просто. Хотим выбрать одну строчку - выбираем! Хотим изменить одну строку - изменяем. Хотим удалить две - удаляем!
Примечание: На самом деле, БД - это не волшебный ящик, и хранит она данные не в нематериальном эфире, а в тех же самых файлах. И точно так же их переписывает. Но делает это она совершенно прозрачно для пользователя.
При произвольном доступе и отсутствии внутренней нумерации «первый-второй-третий», перед нами встает проблема идентификации строк. Допустим, мы вывели строки из базы на экран, и теперь, кликнув по ссылке, хотим отредактировать одну из них. Как её запросить? По содержимому одного из полей? А вдруг это содержимое совпадает с еще несколькими записями? Нам нужен уникальный идентификатор! В MySQL применено остроумное решение. Одно из полей, обычно называемое `id` является автоинкрементным, то есть, автоматически увеличивающимся. При добавлении каждой новой записи, если id не указать или значение равно нулю, база присвоит полю id значение, на единицу большее, чем у предыдущего. Так мы получили уникальный идентификатор – ни у одной строки в этой таблице id не будет совпадать. Теперь очень просто отредактировать или вывести любую запись – достаточно указать её id.
Кстати, у автоинкрементного id есть еще одно побочное свойство. Отсортировав таблицу по этому полю, можно получить ту самую пресловутую первую или последнюю запись :-)
Однако, с этим полем связано множество ошибок и непониманий.
FAQ. ID.
Во-первых, это поле ошибочно принимают за нумератор. Как в классном журнале – 1,2,3-й ученик... А если ученика исключили из школы? А если мы выбираем не всех учеников, а только мальчиков?
Правило первое: id к нумерации не имеет ни малейшего отношения! Во-первых, потому, что id могут идти не по порядку, а во-вторых, что все равно у нас порядок бывает только при ВЫБОРКЕ. Которая может быть какой угодно, id в ней могут идти совершенно вразнобой! Если мы хотим пронумеровать результаты – пожалуйста, при выводе добавим код на PHP, который будет это делать. В ЭТОЙ выборке. Нумеровать надо при выводе. Именно потому, что вариантов выборки может быть бесконечное количество.
Посмотрим, для чего еще новичку может потребоваться нумерация? Для определения количесва выбранных записей. Для этого есть функция – mysql_num_rows(). Она нам поможет при ЛЮБОЙ выборке. В то время, как нумерация не поможет нам вовсе, по причинам указанным выше.
Правило второе: Менять id записи нельзя никогда, ни под каким видом. Во-первых, это просто никогда не нужно. Во-вторых, это же у нас УНИКАЛЬНЫЙ идентификатор. Поле id лишь внешне напоминает цифры. На самом деле – это способ ОДНОЗНАЧНО, и в любое время идентифицировать запись. Допустим, у нас есть сайт с новостями. Кто-то поставил ссылку на новость с id=1. Потом мы этот id сменили. В результате человек придет по ссылке не туда. Если же вам необходимо id перенумеровать – значит, вам просто не нужно автоинкрементное поле.
Язык SQL.
Теперь немного о языке SQL. Это, как я уже говорил – гениальное изобретение человечества. Практически искусственный интеллект. Посудите сами.
Длял того, чтобы выбрать имена всех учеников школы, учащихся в классе 7А, отсортировав их по алфавиту, надо написать такой запрос:
SELECT lastname FROM school WHERE klass=’7A’ ORDER BY lastname
Это практически осмысленное предложение на английском языке!
Попробуем сделать подстрочный перевод:
ВЫБРАТЬ фамилии ИЗ школы [такие,] ГДЕ класс равняется 7А, ОТСОРТИРОВАВ ФАМИЛИИ ПО АЛФАВИТУ
Ну как - неплохо? Мы практически натуральным языком говорим базе, что нам надо – и она выдает нам нужные строки в нужном порядке! И все это ОДНОЙ СТРОЧКОЙ! При этом сложность выборки может быть любой. Если бы мы выбирали из текстового файла – нам бы пришлось написать программу не на один лист. А тут – одна строчка!
Ну как? Вы еще хотите колупаться с файлами?
FAQ. Перенос данных между разными серверами.
Перенос данных посредством дампа - файлов, содержащих запросы INSERT.
То есть, на том сервере, с которого мы хотим перенести базу, мы генерируем файл с запросами INSERT для каждой строки каждой таблицы базы данных. А на удалённом сервере просто исполняем эти запросы.
Наиболее правильный и прямой путь получить дамп - это воспользоваться утилитой командной строки mysqldump
заходим в DOS или в shell и пишем
mysqldump -u<логин> -p<пароль> база > dump.sql
получаем файл dump.sql, который следует перенести на удалённый сервер и исполнить там.
для этого надо вызвать mysql shell таким образом:
mysql -u<логин> -p<пароль> база < dump.sql
всё, база перенесена.
при отсутствии доступа к шеллу можно воспользоваться PHP скриптом
Site Keeper Dumper LE
Практическое использование.
Очень хорошая подборка материалов, обучающих работе с БД есть на сайте "PHP в деталях".
Это уже упоминавшаяся здесь статья Вадима Ткаченко
"Вступление в PHP и MySQL".
А так же статьи Дмитрия Лебебева:
Работа с базами данных. Начало.
Работа с MySQL: Подробнее
Работа с MySQL. Новостная лента для странички
Так же, при работе с MySQL необходимо учитывать требования, излженные в разделе этого FAQ
посвященном составлению запросов и использованию кавычек
обсудить
В начало раздела
Наверх
решение проблемы "Cannot add header information - headers already sent"
Ошибку эту исправить несложно.
Часто такое же сообщение появляется при старте сессий, в немного другой формулировке:
Warning: Cannot send session cookie - headers already sent
Warning: Cannot send session cache limiter - headers already sent
Для начала узнаем, как вообще общается броузер с сервером. Происходит это по специальному протоколу
HTTP. К примеру, когда ты набраешь адрес, или нажимаешь на ссылку, броузер посылает HTTP запрос серверу. Сервер отвечает. Первыми в ответе ВСЕГДА идут HTTP заголовки. Хоть один. И только потом уже сервер посылает, а броузер принимает, текст, или картинку, или файл - в общем, что было запрошено. Cобственно, из-за этого правила - сначала заголовок, а потом информация, и происходит данная ошибка. РНР, для твоего удобства, посылает заголовки автоматически, как только скрипт начинает выдавать бровзеру информацию. Соответственно, если хоть один пробел был уже передан пользователю, заголовки уже ушли, и снова их послать уже никак не можно. А, как ты уже, наверное, догадался, команды
header()
,
setcookie
,
session_start()
, посылают HTTP заголовки.
Разберем теперь это предупреждение.
Warning: Cannot add header information - headers already sent by (output started at /www/script.php:5) on line 20
Cannot add header information - headers already sent
. Все ясно написано. "Не могу послать заголовок, поезд уже ушел" - пишет нам РНР. Дальше РНР сообщает, в каком скрипте и в какой его строке (
output started at /www/script.php:5
) произошел вывод информации, вызвавший автоматическую посылку заголовков. Очень легко найти и исправить. Может быть, там html теги, может быть, echo, а может и просто незамеченая
пустая строка или пробел перед первым тегом
<?.
Очень часто такую ошибку вызывает файл, подключаемый через
include
, в котором либо есть какой-то вывод, либо пустая строка после закрывающего PHP тега - обнаружить ее очень трудно.
Для решения этой проблемы нужно функцию
header
() (или
session_start
(),
setcookie
) и всю логику, которая ее вызывает, поместить ДО любого вывода в броузер. Просто перенести повыше в скрипте.
Иногда вы проверили ВСЁ - нигде ничего нет. Смените редактор. Посмотрите свой файл в другой программе. К примеру, Windows Блокнот при использовании кодировки Unicode добавляет в начало вашего файла служебный символ Byte Order Mark, никак при этом не ставя вас в известность. Откройте скрипт в другом редакторе и удалите посторонние символы. И смените Блокнот на другой редактор.
Многочисленные вопросы на форуме заставляют меня сделать здесь
важное замечание:
Эта ошибка появляется не от того, что у вас в скрипте "что то написано выше". А от того, что РНР выводит что-то в браузер. Это не обязательно код. Это может быть
сообщение об ошибке. может быть пробел или хтмл тег. Да-да. Для самых талантливых: речь идет о любом символе, отправленном в браузер, а не только о тех, которые браузер отображает неискушенному пользователю. У HTML страниц есть исходный текст. И именно он является результатом работы PHP скрипта, а не красивые буковки с картиночками, как думает очень большое количество людей.
В начало раздела
Наверх
Регулярные выражения.
Что такое регулярные выражения?
Это замечательный инструмент для работы с текстом.
Такой же революционный, по сравнению с обычными строковыми функциями, как БД - по сравнению с текстовыми файлами. Это специальный язык для работы с текстом. Причём подчас одна строчка с использованием регулярных выражений может заменить страницу другую обычного кода!
С помощью регулярных выражений можно эффективно искать фрагменты текста любой сложности, заменять одни вхождения на другие.
Основа регулярного выражения - шаблон. С его помощью мы описываем формат нужного нам фрагмента текста, а затем либо проверяем, подходит ли текст под шаблон, либо выразаем одно или несколько вхождений шаблона, либо заменяем на какой-либо текст.
В данном топике собраны все ссылки, которые помогут вам быстро освоить и эффективно использовать регулярные выражения.
Во-первых, это прекрасные статьи для начинающих Сергея Колесниченко (Yukko)
Регулярные выражения, Часть I
Регулярные выражения, Часть II
Материал изложен в лёгкой и доступной форме, снабжён примерами решения часто встречающихся задач. Служит для первичного знакомства с предметом.
При практическом же использовании не обойтись без справочных материалов официальной документации.
В PHP поддерживается два стандарта регулярных выражений - POSIX и PCRE.
Первый считается более устаревшим и медленным, вы не найдёте по нему хороших примеров и даже документация не переведена на русский.
По PCRE (функции preg_*) документация очень солидная.
Во-первых, это подробнейшее изложение синтаксиса и пояснение значения всех спецсимволов -
Синтаксис регулярных выражений
Во-вторых, -
Общее описание, список функций и полезные комментарии
В-третьих, пояснение довольно важного элемента -
Модификаторов шаблонов
Ну, и документация на все функции, разумеется. Основными из которых являются
preg_match
,
preg_match_all
и
preg_replace
с незаменимыми комментариями пользователей.
Всё (кроме комментариев) - на русском языке.
Нельзя, так же, обойти вниманием фундаментальный труд столпа российского PHP Дмитрия Бородина,
Регулярные выражения в PHP (сравнение Perl и PHP)
чтобы данный текст не выглядел сухой теорией, приведем пример решения наиболее распространённой задачи - "подсветка ссылок" или "превращение
http://phpfaq.ru в ссылку"
$text=preg_replace("#(https?|ftp)://\S+[^\s.,>)\];'\"!?]#",'<a href="\\0">\\0</a>',$text);
Им можно пользоваться, не понимая ни слова. А узнать, что означают эти закорючки, можно из ссылок выше :-)
В начало раздела
Наверх
Различие между абсолютными и относительными путями. В файловой системе и на сайте.
твой сайт существует в как бы в двух измерениях.
Реальном и виртуальном.
Для всех посетителей - это виртуальный веб-сервер. Который отличается, в числе прочего, тем, что на нем НЕ СУЩЕСТВУЕТ ФАЙЛОВ. если ты пишешь
http://site.ru/file.html
- это не файл. Это URI, виртуальный адрес. Никакого файла с именем file.html на сервере может вообще не быть. Это все виртуальные адреса, а не файлы.
И браузер работает именно с адресами.
Для разработчика - это программа, выполняющаяся на совершенно конкретном реальном компьютере. С совершенно конкретным жестким диском, каталогами и файлами. И скрипт, работая со своими данными, подгружая другие скрипты, работает именно с реальными ФАЙЛАМИ, на физическом ДИСКЕ.
Вот в этом различии и кроются трудности, с которыми часто сталкиваются новички.
Теряют файлы, путают ссылки с файлами, обращаются к локальным файлам по протоколу HTTP, или инклюдят файлы от корня веб-сервера.
А всего-то надо четко понимать две вещи:
1. Различать корень веб-сервера, как его видит браузер, и корень файловой системы на диске.
2. Отличие относительных путей от абсолютных.
Начнем со второго.
Это очень просто. Если путь указывается от корня системы, то это путь абсолютный. Это как почтовый адрес в реальной жизни - откуда бы ты не шел, но по точному адресу ты всегда точно найдешь нужное место.
примеры абсолютных путей:
/var/www/site/forum/index.php
/img/frame.gif
с:\windows\command.com
В юникс-системах и на веб сайтах корень обозначается косой чертой - "/".
Это важно. Это не просто палочка, а самостоятельный АДРЕС, путь.
В адресе
http://www.site.ru/
последняя косая черта - не для красоты! Она обозначает вполне конкретный адрес - начало сайта.
На диске в юникс системах так же можно набрать "cd /" и ты попадешь в корневой каталог.
В виндоус системах файловая система разбивается по дискам, поэтому, в абсолютном адресе надо указывать имя диска. Абсолютного корня всей файловой системы в виндоус нет, у каждого диска - свой. Например, C:\ E:\
поэтому, даже если путь в виндоус начинается с косой черты, то это не абсолютный путь, а относительный. Относительно текущего диска. А абсолютный начинается с буквы.
Если в начале пути корень не указать, то этот путь будет относительным, и он достаивается от текущего положения. В реальной жизни это напоминает дорогу к винному магазину - "два квартала налево и там все время прямо". Дойти по такому пути можно только из конкретной точки. Из другой ты попадешь уже в совсем другое место.
Самый простой пример относительного пути - это просто имя файла.
Если файл находится в том же каталоге, с которым работает программа - она его найдет, добавив текущий путь к имени файла.
примеры относительных путей:
file.php
(фал лежит в той же папке)
./file.php
(фал лежит в той же папке. такая запись иногда требуется в некоторых юникс системах)
images/picture.jpg
(файл лежит в капке images, которая находится в текущей)
../file.php
(файл лежит в папке, которая расположена на один уровень выше от текущей)
../../file.php
(файл лежит в папке, которая расположена на два уровня выше от текущей)
И операционная система, и браузер, встретив относительный путь, достраивают его до абсолютного. но каждый - по-своему.
Веб-сервер и диск. В общем-то, из предыдущих объяснений уже все должно быть понятно.
На диске путь к файлу скрипта может быть таким:
/var/www/site/forum/index.php
В то же время, виртуальный адрес этого скрипта при просмотре через браузер, будет:
http://www.site.ru/forum/index.php
На этом примере легко увидеть, где пересекаются два измерения: у этих двух адресов есть общая часть -
/forum/index.php
- и она-то и служит причиной путаницы.
Для браузера это самый полный путь, который только может быть. Он начинается от корня сайта.
Для скрипта же, исполняющегося на сервере - это всего лишь ЧАСТЬ пути.
для скрипта путь
/forum/index.php
окажется несуществующим - в корне диска нет каталога forum!
чтобы получить полный путь для того, что на сайте выглядит, как
/forum/index.php
, надо приставить слева к нему путь к папке, которая считается корневаой для всего веб сервера.
в нашем примере - это
/var/www/site
Этот путь задается в кофигурации веб-сервера и именно он содержится в системной переменной PHP
$_SERVER['DOCUMENT_ROOT']
В виртуальном же сервере - том, который видит пользователь - наоборот, нет никакого диска. Есть корень сайта. То есть, для того, чтобы любая ссылка гарантированно работала, независимо от того, из какого места сайта она вызывается, она должна быть абсолютной.
Если у вас на сайте есть, допустим, два раздела:
http://www.site.ru/about/info.php
и
http://www.site.ru/job/vacancy.php
то, если в файле
info.php
сделать ссылку просто на
vacancy.php
, то браузер ее не найдет - он будет искать адрес
http://www.site.ru/about/vacancy.php
, достраивая путь от текущего каталога.
Поэтому надо писать полный путь от корня сайта -
/job/vacancy.php
Всё это касается, естественно, не только тегов
<a>
но и
<img>
и любых других, где используются ссылки на другие файлы.
Ссылки на локальные адреса следует писать без указания протокола и домена - только путь от корня сайта -
/job/vacancy.php
. Ссылки же на другие сайты следует писать полностью -
http://www.site1.ru/job/vacancy.php
.
PHP предоставляет множество средств для работы с файлами, каталогами и URL-ами.
Во-первых, это многочисленные предопределённые переменные, которые описаны в
документации и значения которых в своём скрипте пможно посмотрев с помощью
phpinfo()
:
Константа __FILE__ содержит имя текущего исполняемого файла.
В отличие от PHP_SELF она содержит имя файла, исполяющегося в данный момент.
В начало раздела
Наверх
Ссылки на полезные ресурсы
Основные
ЧПУ, mod_rewrite
Готовые решения
Разное
Основные
www.google.com. Это, без шуток,
самая важная ссылка по PHP. При некотором умении с её помощью можно найти ответ на любой вопрос. Но даже и не обладая особыми навыками в поиске, можно получать порясающие результаты. Например, просто введите в строку поиска ту ошибку, которую выдал РНР.
php.spb.ru. Самый известный, наверное, российский ресурс, посвященный PHP. Во всяком случае, Яндекс, Гугль и я считаем именно так. Cледует учитывать, что большая часть информации там безвозвратно устарела (к примеру, информация по сессиям), а частично была изначально неверна (Оптимизация программ на PHP). Поэтому, обязательно надо обращать внимание на год написания.
Однако разработки Дмитрия Бородина до сих пор великолепны, а его преподавательские таланты - непревзойдённы.
PHP на Спектаторе. статьи Дмитрия Смирнова ака Spectator. Многое, конечно, устарело, но в целом достойный ресурс.
Портал своими руками Описание работы с шаблонами на примере движка x-template от Евгения Бондарева.
Как правильно задавать вопросы. Обширный текст, который реально может помочь с тем, как найти ответ на свой вопрос, и как правильно задать его в форуме. Не стоит пугаться его объема. Если вы действительно хотите освоить PHP, научиться эффективно пользоваться интернетом и значительно повысить свой профессиональный уровень в любой области - обязательно прочтите его.
ЧПУ, mod_rewrite
ЧПУ и PHP. Классическая статья Spectator (Дмитрия Смирнова) из Новосибирска
Имитация файлов и директорий - Классическая статья DJ Rabbit (Дмитрия Лебедева) из Новосибирска.
Модуль mod_rewrite. Цикл из 4 статей о mod_rewrite на сайте Sitemaker.
Apache URL Rewriting Guide и mod_rewrite documentation Переводы Александра Егорова.
Готовые решения
Рисование календаря
Как разбить вывод из mysql постранично
Как сделать уменьшенную копию картинки? Подробная статья на php5.ru
Как установить права на файлы,
подробно и с красочными иллюстрациями.
Разное
Использование CRON и команды crontab
. Автоматический запуск сервером скриптов по расписанию
Небольшая и очень остроумная блиотечка phpfront. Служит для вывода текста растровыми шрифтами при рисовании графики средствами модуля GD. Идея проста до гениальности - весь шрифт записывается в один файл PNG, нужные буквы вырезаются из него и наакладываеются на вашу картинку. Никаких проблем со шрифтами, локалями и версиями gd!
Гради Буч. Объектно-ориентированный анализ и проектирование. Библия ООП. Написана на примере С++, но полезна всем, кто осваивает этот метод программирования.
Почтовый стандарт "MIME" (RFC1521).
Если вы работаете с почтой - формируете письма, добавляете вложения, хотите вставить картинки - этот текст обязателен к прочтению.
rfc-editor.org. Полное собрание стандартов интернет. На английском. Если вы хотите узнать тонкости протоколов HTTP, FTP, TCP/IP и любых других - вам сюда.
В начало раздела
Наверх