пятница, 18 декабря 2009 г.

Ошибки в PHP. Вывод, перехват, скрытие.

Ошибки, могут быть как друзьями программиста так и его врагами. Как говорится у каждой стороны две медали.
 Насколько часто вы бьетесь над программой, восклицая про себя: «Чего же ей еще не хватает?!». Помню, когда я был новичком, в самом начале пути познания PHP, у меня это было довольно часто, пока я не научился читать и понимать ошибки. Не стоит воспринимать ошибку как препятствие. Это подсказка для вас. Описание проблемы. Намного легче заниматься отладкой когда, если что-то не работает, видишь ее перед глазами. Поэтому, во время отладки стоит их включать если они отключены. Включаются ошибки достаточно просто. Можно включать их как через .htaccess так и с помощью самого PHP кода. 

далее

понедельник, 7 декабря 2009 г.

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

Наверное, этот пост следовало написать с самого начала, но я, честно признаться, как-то не думал об этом. На мысль описания работы программистов меня натолкнули..вы не поверите, именно расплодившиеся в огромном количестве сайты SEO тематики. Слишком много людей сейчас хотят зарабатывать большие деньги легко, поэтому многие пытаются познать SEO, забывая что ничего в этом мире легко не дается и на 10-20 человек занимающихся раскруткой сайтов только 1 имеет действительно хорошие прибыли. Но, я сейчас не об этом. <--more-->
Бытует мнение, что программисты получают достойные деньги за свою работу, ведь кому как не им, работающим «мозгами» получать «бабки». Но это далеко не правда. Действительно хорошие деньги получают либо Team лидеры, которые являются Профессионалами. Именно так, с большой буквы. Либо же те, кто занимаются исключительно своим проектом и проект удачен. И тех и других не очень большое число. В большинстве своем деньги весьма средние, а труд…ну я сейчас опишу, а вы судите сами. Работать приходится не только по 8 часов на работе, но иногда и дома, часто до ночи. Так в общей сложности у компьютера я провожу порядка 12 часов в сутки, что отнюдь не положительно сказывается на здоровье. Кроме того, у каждого программиста, я думаю, бывают периоды «отупения», когда чего-то не хватает и мозги полностью отключаются к чертям собачьим. Работодателю же все равно что вас там тревожит, он ставит сроки и платит деньги и, не взирая на ваше состояние, вы должны сдать проект в срок. Бывало так, что чтобы успеть к срокам спал по 4 часа в сутки.. Можно так же рассказать и о недобросовестности заказчиков, если говорить о фрилансе, и о неудавшихся по причине, например непроработанности дизайна (не зависящей от вас), проектах.. о самодурстве заказчиков которые не прислушиваются к вашему мнению на выходе, получая фиг знает что, только потому что не захотели услышать вас. Нюансов куча…
Вы только не подумайте, что я жалуюсь на жизнь. Нет, я люблю свою работу, я могу сидеть ночами (до определенного предела разумеется), ибо мне это интересно, и это самое главное. Если вы считаете, что программирование принесет вам золотые горы и только поэтому осваиваете PHP-хочу вас огорчить это не так…да и нелюбимое занятие превратится в адскую муку, если заниматься им каждый день. Поэтому настоятельно рекомендую еще раз подумать, а надо ли оно вам…учиться программировать.

пятница, 4 декабря 2009 г.

MySQL, создаем первую таблицу.

В этой статье, я постараюсь кратко рассказать о достаточно необьятной теме, типах столбцов(данных) в MySQL.
Итак, пришла пора вам задуматься о создании первого более-менее серьезного скрипта. Например гостевой книге. Как же хранить сообщения в ней? Можно конечно в файликах, но задумайтесь какой гемморой это. Если сообщений много => много мелких файликов..а это не есть гуд. Да и листинг сообщений (не вываливать же на одну страницу например 1000 постов) тоже гемморой еще тот. что ж нам помогут базы данных. В них легко можно хранить информацию.

вторник, 1 декабря 2009 г.

Новый релиз PHP 5.3.1

19 ноября команда разработчиков PHP представила новый релиз 5.3.1 направленный на увеличение стабильности ветки 5.3.x По завялениям разработчиков исправлено более 100 ошибок, некоторые из которых связаны с безопасностью. Всем рекомендуется обновиться до этой версии.
Вот некоторые из изменений:

  1. Добавлена директива «max_file_uploads» в php.ini, которая может установить количество запросов при закачке файлов, для предотвращения DOS атак.
  2. Исправлен обход режима safe_mode в tempnam()
  3. Исправлен обход «open_basedir» директивы в функции posix_mkfifo
  4. Исправлено отсутствие safe_mode_include_dir

Более подробный лог изменений здесь.

суббота, 14 ноября 2009 г.

MySQL, или удобное хранение данных.

Собственно, что такое MySQL? Это средство для удобного хранения информации. Согласитесь с файлами работать неудобно, а особенно это неудобство чувствуется если их очень много. А MySQL спокойно справляется с 25-гигабайтной базой..не без напрягов конечно, но в целом весьма неплохо.
Итак SQL-Структурированный Язык Запросов. "Почему же я заговорил о нем, ведь данный ресурс посвящен PHP",-думаете вы. Да все просто. В PHP очень хорошо реализована схема работы c базами данных (БД) MySQL. Приведу простой пример, если вы ничего не понимаете в MySQL не расстраивайтесь, пока вам это и не нужно, позднее постараюсь немного обьяснить что к чему. Сейчас лишь разберитесь как с ним общается PHP.

0;");
//посылаем запрос к MySQL

if(mysql_num_rows($query))
{
//mysql_num_rows возвращает количество строк выбранных в БД
while($data = mysql_fetch_assoc($query))
{
//В цикле берем результат запроса в массив и выводим

print '
';

print_r($data);

print '

';
}
}
?>

Итак что же за белиберда здесь написана? Для начала нам надо подсоединиться к MySQL для этого используем mysql_connect, где первый параметр сервер к которому подключаемся, второй-имя пользователя БД, третий-пароль пользователя БД. После чего выбираем БД с которой хотим работать с помощью mysql_select_db. Далее, шлем составленный нами, запрос к серверу. Получаем идентификатор (ресурс id наподобие идентификатора открытого файла) и читаем результаты в массив при помощи цикла while и оператора mysql_fetch_assoc. Но перед этим, чтобы цикл нам не выдал ошибки, нужно проверить, а есть ли вообще результаты. В этом поможет функция mysql_num_rows, которая считает количество результатов, возвращенных MySQL. Конечно это примитивный пример, но функции эти основные, без которых освоиться с MySQL будет просто нереально. Настоятельно рекомендую почитать в мануале как они ведут себя.
Так же, часто можно использовать вместо mysql_fetch_assoc другую функцию mysql_fetch_array, которая в зависимости от параметра создает или ассоциативный или пронумерованный или смешанный массив результатов. Достаточно часто это бывает очень удобно. При работе с базами данных надо всегда помнить, что большое количество запросов, или очень сложные запросы, могут сильно напрячь сервер и, если вы хоститесь, у обыкновенного хостера, а не на ВДС или Дедике надо как можно сильнее оптимизировать работу с MySQL. К примеру настоятельно не рекомендуется использовать в цикле запросы, даже очень простые. На странице, на мой взгляд, не должно быть более 20-30 запросов (в зависимости от посещаемости ее пользователями, возможно, если нельзя отказаться от запросов, стоит как-то кэшировать ее) . Ну на этом пожалуй закончу, ибо о MySQL можно говорить довольно долго и существует очень много различных аспектов работы с ней. В дальнейшем постараюсь вернуться к этому вопросу и, как можно более подробно, в рамках моего ресурса разумеется, описать MySQL

среда, 28 октября 2009 г.

Ускорение работы сценариев PHP

Любой уважающий себя программист должен понимать, что сервер имеет конечное число ресурсов, которые рано или поздно заканчиваются. Поэтому требуется как можно тщательнее оптимизировать программный код, дабы потом не хвататься за голову и не сокрушаться что сервера не справляются. Каким же образом оптимизировать код? На самом деле, если не затрагивать MySQL (о чем надо, я считаю, говорить отдельно), способов оптимизации не так уж и много. Точнее их не мало, но результат от них, по отдельности очень маленький, а суммарно, как говорится, «копейка рупь бережет».. Сейчас я хочу перечислить то, что знаю, и чем очень часто пользуюсь.

  1. Вы должны осознавать что при преобразованиях (preg_replace, str_replace) регулярки используют гораздо больше ресурсов чем строковые функции, поэтому рекомендую там где можно обойтись использовать именно str_replace или str_ireplace
  2. Помните о том, что в большинстве случаев, если все же надо использовать регулярку preg_match работает быстрее чем eregi
  3. Незачем генерировать файлы содержащие большие обьемы данных, если часто с ними надо работать сценарию. Гораздо лучше использовать множество мелких файлов. Хотя и в количестве файлов надо стараться знать меру.
  4. Незачем повторно выполнять одни и те же действия если вы можете создать переменную, которая будет содержать результат действия.
  5. Надо помнить, что например функция echo при выводе работает быстрее чем print, а вывод заключенный в одиночные кавычки работает быстрее чем в двойные. Связано это с тем, что в двойных кавычках текст еще и обрабатывается (переменные преобразуются), а в одиночных выводится как есть.
  6. Не стоит вводить переменные с длинными именами, в дальнейшем это может аукнуться весьма сильно.

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

вторник, 13 октября 2009 г.

Как я прикручивал php мануал (часть 2)

Прошу прощения за продолжительный перерыв, но к сожалению затянула рутина и работа, просто физически не было времени продолжать писать здесь.
Итак сегодня я хочу продолжить свой рассказ о том как я прикручивал мануал на данный ресурс.
В прошлой статье я jgbcfk, как возможно преобразовать html мануал под свои нужды. Надеюсь, что вы разобрались, что к чему. Ну что ж продолжим.
Мне требовалось интегрировать страницу в тело вордпресса. Они уже были подготовлены для этого, но полностью страница html мне была не нужна. Надо было выдернуть лишь часть ее внутри тэгов body. Вот тут-то мне и понадобились регулярки. Нет можно было конечно не осваиваться с регулярками, а взять мою любимую функцию explode и с ее помощью все сделать, но это было бы нудно, и, некрасиво. Согласитесь гораздо приятнее, когда весь код выглядит «элегантно». Вот примерно такая функция работает у меня при запросах к мануалу php:


<?php

function HTML2WPDo()

{

    
preg_match('@([0-9A-Za-z_\.\s]+)@i',$_POST['search'],$search);

    
$search $search[1];

    
preg_match('@([\d\w_\.\s\-]+)@i',urldecode($_SERVER['QUERY_STRING']),$page);

    
$page $page[1];

    
//print $page;

    
$dir get_option('dir4html');

    
$abs_dir $_SERVER['DOCUMENT_ROOT'].'/'.$dir;

    if(
$search)

    {

        
$search str_replace('_','-',$search);

        
$content_file 'function.'.$search.'.html';

        if(
file_exists($abs_dir.$content_file))

        {

            
$man_func file_get_contents($abs_dir.$content_file);

        }

        else 
$content 'Произошла ошибка. Функция с подобным именем не найдена!';

    }

    else 

    {

        if(!
$page$page 'index';

        if(
file_exists($abs_dir.$page.'.html'))$man_func file_get_contents($abs_dir.$page.'.html');

    }

    
$count preg_match("|<body([^>]*)>(.*?)<\/body\s*>|si",$man_func,$func_body);

    if(
$count

    {

        
$content $func_body[2];

        
$func_body '';

    }

    return 
$content;    

}

?>

Что же она может? Данный алгоритм может как искать по имени функции, так и просто отдавать требуемые страницы. Хочу заметить что сделано все достаточно примитивно, ибо мне не нужны были какие-то изыски, единственное на данный момент что я хочу доработать это чтобы для каждой страницы в мануале генерился свой title и meta-description, но пока к сожаленеию не дошли руки. Ну это все на будущее, а теперь рассмотрим то что есть.
Первая строка:


<?php

preg_match
('@([0-9A-Za-z_\.\s]+)@i',$_POST['search'],$search);

?>

Здесь в строке поиска (элемент массива POST с ключом search) мы смотрим чтобы значение соответствовало шаблону(только цифры, латинские символы, точка, пробел, нижнее подчеркивание). Результат в виде массива помещается в переменную $search. Если выражение будет соответствовать то первый элемент массива как раз и будет содержать его.
Дальше подобную же проверку проходит элемент глобального массива $_SERVER['QUERY_STRING'] (для запросов к различным страницам мануала используется именно этот элемент).
После чего нам требуется получить дирректорию в которой лежит мануал. Так как все написано под вордпресс то я воспользовался функцией WP которая получает сохраненные в админке данные(дирректорию в данном случае).


<?php

$dir 
get_option('dir4html');

$abs_dir $_SERVER['DOCUMENT_ROOT'].'/'.$dir;

?>

Далее если переменная $search не пустая-проверяем существует ли файл с такой функцией (все файлы мануала имеют удобное для нас имя. function.имя функции.html), если такой файл существует-читаем его в строку.
В ином случае:
если не задана $page выдаем индекс;
иначе ищем файл с таким названием и если существует читаем в строку.
Ну, а дальше самое «сладкое»:


<?php

$count 
preg_match("|<body([^>]*)>(.*?)<\/body\s*>|si",$man_func,$func_body);

?>

регулярное выражение. Так как у боди могут быть параметры используем ([^>]*)
т.е любой символ, но не «>» и данные символы могут повторяться 0 или более раз (благодаря «*»).
(.*?) – это означает любой символ любое количество раз. Ну и ищем все это в переменной $man_func и пишем в $func_body. Таким образом $func_body[2] будет содержать именно то, что нам надо. (почему читайте в предыдущей статье цикла) Ну и собственно возвращаем результат обработки:


<?php

return $content;

?>

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

четверг, 1 октября 2009 г.

Регулярные выражения в PHP или как я прикручивал мануал (часть 1)

Долго думал стоит ли начинать писать статью на данную тему…и в конце концов решил почему нет? Я не очень хорошо знаю регулярные выражения, но то что у меня уже получилось-этим я могу поделиться с читателями. Заранее просьба к гуру, давно и хорошо знающим регулярки не ругать сильно данную статью и просто если есть возможность указать на недочеты. Ну это была преамбула. Приступим.
Я давно хотел прикрутить на мой блог PHP мануал в формате html дабы проще было ссылаться на различные функции. Но все как-то руки не доходили. И вот наконец-то вырвался из рутины и решил, что надо просто сесть и написать.
Просто вставить php мануал на сайт было не интересно да и просто стремно. Ведь ман был без дизайна, обычные белые страницы. Мне нужно было интегрировать его в CMS. Тут же я столкнулся с первой проблемой: я никогда не ковырялся в коде WordPress, ну вот не довелось как-то. Ну, что нам стоит дом построить, нарисуем будем жить. :) Дабы сэкономить свое время, я ведь не собираюсь досконально изучать данную систему чтобы постоянно писать под нее плагины, я просто взял несколько плагинов, которые уже были подключены у меня и отлично работали и стал разбираться как же там все устроено. Оказалось все достаточно просто. Ну описывать что и как там я не буду. Ибо статья посвящена не этому(но в дальнейшем обязательно все опишу ;) ). Итак есть мануал, в html форме, есть желание прикрутить его на сайт, и мы разобрались как устроен WP(ну это конечно громко сказано, но все же).
Во первых я решил что в $_SERVER['QUERY_STRING'] будет содержаться имя файла к которому в данный момент обращается пользователь. Т.е например вы ищете информацию о функции substr на сервере файл с информацией о данной функции имеет путь /manual/function.sunstr.html чтобы обратиться к нему используем адрес /php-manual/?function.substr. Ну вот так вот все достаточно просто. Но вот все линки в html файлах старые (/manual/function.sunstr.html) а мне надо было чтобы они соответствовали моей системе. Что ж…вариантов два. Преобразовывать на лету регуляркой (apache или php не важно) или преобразовать один раз. Я решил что ресурсы сервера не бесконечны (преобразование на лету всегда неслабо грузило проц). Значит надо преобразовать единожды… Тут мне помогут регулярные выражения. Надо сказать, что знаю я их весьма поверхностно. Ну что ж…как говорится: «Иду на вы!».
И я начал свои изыскания. Могу сразу сказать, что промучался я пол дня, прежде чем получил нормальный результат, ну ничего тяжело в ученье-легко в бою. Потом будет проще. Вот что у меня получилось:


<?php

$arr_files 
glob('./manual/*.html');

$i 0;

foreach (
$arr_files as $filename)

{

    
$file_data file_get_contents($filename);

    
$file_data preg_replace('!<a(.*?)href="([^"]*)\.html((\#([^"]*))*?)"!is',

    
'<a\1href="?\2\3"',$file_data);

    if(
file_put_contents($filename,$file_data))

    
$i++;

}

print 
'Изменено '.$i.' сстраниц';

?>

Итак что же здесь написано? Первый пункт чтение дирректории с файлами. В этом нам помогает функция glob. Она получает все имена файлов по маске. В данном случе все файлы с расширением .html. Результат работы данной функции-массив данных с именами файлов. Теперь в цикле перебираем данный массив. В этом нам помогает foreach. Читаем файл в переменную-строку(file_get_contents). А вот теперь начинается самое интересное. Обработка ссылки и замена. Функция preg_replace-специальная функция регулярок, она производит поиск по тексту и замену соответствующего шаблону (регулярке) выражения на то что мы хотим.
Во первых надо помнить что любое регулярное выражение обрамляется либо парными символами (скобками например такими[]), либо одинаковыми символами, например как у меня !…!.
Вне данных символов(а точнее после) ставятся модификаторы. В моем случае модификаторы is. Модификатор i означает, что поиск ведется без учета регистра символов..а s здесь для того чтобы точка(которая обычно означает любой символ кроме перевода строки) означала и перевод строки. Таким образом мы пишем часть выражения (<a(.*?)) означающую что после тэга a может стоять любое количество любых символов. Звездочка означает повторение предыдущего символа 0 или более раз, а знак вопроса умеряет ее жадность). После чего пишем href="([^"]*)\.html((\#([^"]*))*?)"
([^"]*) означает что возможны любые символы, но не кавычки. Т.е знак ^ в квадратных скобках можно перевести как «не». Далее идет расширение файла в линке (\.html). Так как точка это спец символ ее надо экранировать обратным слэшем (так же как и далее экранируется решетка). Далее пользуемся тем же приемом что и ранее (([^"]*)) и указываем что выражение с решеткой может повторяться 0 или более раз. Это все конечно весьма сложно для понимания с нуля поэтому советую заглянуть на сайт pcre.ru дабы было понятнее. Внутри регулярки все что в круглых скобках мы получаем при поиске записывается в некий массив. Данные из которого мы можем вытянуть посредством \1\2\3 как это описано в строке замены (<a\1href="?\2\3").
Ну надеюсь в общем и целом вы разобрались что к чему и уловили основную суть. Собственно после этого просто запускаем скрипт и проверяем, что мы получили. Все линки должны переконвертироваться так, как нам надо. На этом я пожалуй закончу данную статью, дабы не перегружать читателя информацией и не валить все в одну кучу. Но прикручивание мануала на этом далеко не закончено и в скором времени (я надеюсь) выйдет продолжение. Надеюсь что данная информация была вам интересна и полезна.

пятница, 25 сентября 2009 г.

Количество скачиваний файла на PHP

На одном из форумов мне задали вопрос: «Как реализовать подсчет количества скачиваний файла?». Покумекав немного я решил написать пример подобной реализации с использованием не баз данных, но файлов. И так приступим. Прежде всего надо разбить задачу на более простые подзадачи.
1) Как подсчитывать;
2) Как хранить подсчитанные данные;
3) Как их выдергивать и преподносить пользователю.
Это-наш план реализации. Давайте теперь разбираться по пунктам, что и как надо сделать. Прежде всего подсчет. Понятно что напрямую файл отдавать нельзя прежде чем его отдать надо прибавить к счетчику +1. Значит это реализуем примерно вот так:


<?php

//код файла req.php

define('URL_DIR','http://phpbegun.ru/files_dir/');

define('ABS_DIR',$_SERVER['DOCUMENT_ROOT']);

//Определяем нужные нам константы

$namefile htmlspecialchars(str_replace("/","",$_GET['name'])); 

//Через гет передаем параметр-имя

if(!$namefile

{

    echo 
'Произошла ошибка! Файл с таким именем не найден.';

}

$array = array(); //массив данных

if(file_exists(ABS_DIR.'/schet.txt'))

{

    
$array unserialize(file_get_contents(ABS_DIR.'/schet.txt'));

    
//Файл который будет содержать данные о кол-ве скачиваний

    //в виде сериализованного массива

    
if(!$array[$namefile]) $array[$namefile] = 0;

    
$schet $array[$namefile]+1;

    
//$array[$namefile] содержит кол-во скачиванй этого файла

}

else 

{

    
$schet 1;

}

$array[$namefile] = $schet;

//присваиваем новое значение элементу массива

$array serialize($array);

//сериализуем данные

@file_put_contents(ABS_DIR.'/schet.txt',$array);

//пишем в файл причем не проверяем 

//записалось или нет ибо скачивание 

//должно начаться независимо от этого 

header("Location: ".URL_DIR."$namefile");

//Переадресуем запрос на скачиваемый файл

?>

Итак первая часть кода есть. Данный скрипт должен выполняться перед началом скачивания файла, т.е. на него должны вести все ссылки с вашего сайта для скачивания. Этот сценарий подразумевает что права на корневой дирректории и на самом файле будут таковы чтобы была возможна запись (cmod 0777). Так же хочу заметить, что для больших файлохранилищ даный алгоритм не лучшее решение и гораздо правильнее было бы использовать MySQL. Но для тех у кого небольшой сайт с малым количеством файлов это наиболее оптимальный вариант. Фактически мы решили задачи 1 и 2. Храним данныее в файле в сериализованном виде (настоятельно рекомендую почитать о функциях serialize и unserialize в официальном мануале, очень полезная штука). Кроме того сначала подсчитываем количество скачиваний, увеличиваем его, сохраняем в файл и потом выводим. как же теперь преподносить данные пользователю? При формировании страницы надо лишь считывать массив данных, и выдергивать с именем данного файла нужное нам число. Примерно вот так:


<?php

define
('URL_DIR','http://phpbegun.ru/files_dir/');

define('ABS_DIR',$_SERVER['DOCUMENT_ROOT']);

$data unserialize(file_get_contents(ABS_DIR.'/schet.txt'));

echo 
'Вот тут можно скачать файл '.

'<a href="/files_dir/req.php?name=name.txt">Names(',$data['name.txt'],')</a>';

?>

Простейший счетчик скачиваний файлов готов. Советую вам все define вынести в отдельный файл, чтобы не определять их и в файле скачивания и в файле вывода, и подключать через require_once. На этом пожалуй закончу данную статью, ибо пищу для размышлений я вам дал, а что-то более интересное и элегантное вы сможете конечно же написать и сами если постараетесь. Надеюсь, что вы поделитесь своими вариантами решений, будет интересно посмотреть.
Удачи в обучении :)

среда, 23 сентября 2009 г.

Cookie что это такое и с чем их лучше есть)

Ну есть их лучше конечно с чаем) Cookie с английского переводится как печенье. Фактически это те данные которые мы можем сохранить на машине пользователя в браузере именно для нашего сайта. Проще всего посмотреть список кукисов для определенного сайта в опере. В моей 10 надо нажать инструменты->настройки->выбрать вкладку Дополнительно->cookie->управление Cookie. Ну вот теперь вы повелитель печенекь на своем компьютере:) Зачем они нужны? Ну например это удобно для примитивной идентификации пользователя (Гораздо безопаснее важные данные хранить в сессиях а не куках, но об этом я напишу позднее). Ну хватит «воды» пора переходить к конкретике. Итак мы разобрались что cookie хранятся у пользователя в браузере, но как же с помощью php их туда засунуть? Есть такая функция setcookie именно она задает их. Надо помнить, что cookie должна быть заданы до того как будут отправлены какие либо данные пользователю(т.е до какого-либо вывода на дисплей юзера). Я приведу простой пример как задаются кукисы, сделаю счетчик количества просмотров страницы, для каждого отдельного пользователя.


<?php

if(!$_COOKIE['count']) setcookie('count',1); 

//Если в глобальном массиве кук нет такого элемента, то создаем его

else $_COOKIE['count']++;

//иначе просто к существующему значению плюсуем 1

echo 'Вы просмотрели данную страницу ',$_COOKIE['count'],' раз';

?>

Вот собственно и вся премудрость. В массиве COOKIE будет доступен данный элемент после следующей перезагрузки страницы. Надо заметить, что данная кука будет «жить» пока пользователь не закроет браузер, после чего она просто исчезнет, но бывают случаи когда надо задать cookie на гораздо дольший срок. Как раз для этого у setcookie имеет третий параметр, а именно время жизни кукиса. Задается он примерно вот так:


<?php

setcookie
('count',1,time()+3600); 

//Ставим значение для элемента массива $_COOKIE['count']

//равным единице и задаем время жизни куки один час

?>

Но и даже это еще не все. Иногда нужно задать куку для определенной дирректории. или для какого то из субдоменов вашего сайта. Тогда делаем вот так:


<?php

setcookie 
("count"1,time()+3600"/2009/"".phpbegun.ru"1);

?>

Для дирректории 2009 начиная от корня сайта я устанавливаю куку для всех субдоменов и домена сайта phpbegun.ru . Последний параметр равный единице обозначает то, что cookie защищенная, т.е будет отдаваться лишь в том случае, если используется HTTPS соединение. Ну вот, теперь вы знаете что такое кукисы и с чем их лучше есть)

понедельник, 21 сентября 2009 г.

Выбор редактора для php

В свое время, когда я еще только учился программированию, я редактировал скрипты в допотопном стандартном notepad’е винды. В связи с тем что там не было подсветки синтаксиса, и других функций, которые сильно облегчают жизнь программисту на сегодняшний день, в моем коде была куча синтаксических ошибок, исправление которых сжирало чертову кучу времени. А согласитесь время-не тот ресурс который стоит разбазаривать зря. после чего я занялся поиском редактора кода для себя. Пробовал PHP Expert Editor, но как то не особо понравилось, возможно не оценил. Остановился для себя на приложении с открытым исходным кодом Notepad++ (вот русскоязычная версия ресурса данного редактора: notepad-plus.sourceforge.net, и вот ссылка на последний на момент написания редактор npp.5.5.Installer) Редактор достаточно удобен, имеет возможность перекодировки файлов, кучу настроек, может подсвечивать синтаксис как php так и других языков, кроме того имеется возможность подключать легко и непринужденно различные плагины, например для работы с фтп с помощью данного приложения. Плюсов у данной программы конечно много, но есть минус, который лично для меня фактически перечеркнул все плюсы-это малая поддержка кодировок. Он поддерживает только ANSI кодировки, UTF-8, UCS-2. А в той конторе, в которую я тогда устроился сайт был в koi8-r, соответственно все скрипты были в отвратительных кракозябрах после моего редактирования. Пришлось искать новый редактор. И наконец более опытные коллеги посоветовали мне самый лучший (на мой взгляд), но и самый тяжелый редактор. Zend Studio (оффициальный ресурс Zend. Это фактически полнофункциональная среда для разработки на php включающая все от самого web-сервера и mysql сервера до браузера для просмотра (ну движок он дергает все таки IE :) ). К сожалению данное ПО не бесплатно, но, я думаю сами знаете что для вас в поисковике будет найти не проблема) Данная система разработана теми же людьми кто и разрабатывает php поэтому она максимально заточена под нужды PHP разработчика. Советую освоить ее и пользоваться именно ею. Удачи.

четверг, 17 сентября 2009 г.

Работа с массивами

Собственно что такое массив? Для новичка проще всего представить массив таблицей, в одном столбце которой ключи, а в другом значение. Зная ключ мы можем получить значение. Ну или наоборот, если очень надо) Но давайте не будем спешить. Итак таблица:

Ключ Значение
yellow банан
green яблоко
red Томат

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


<?php

$array 
= array(

'yellow'=>'банан',

'green'=>'яблоко',

'red'=>'томат');

//или

$array['yellow'] = 'банан';

$array['green'] = 'яблоко';

$array['red'] = 'томат';

?>

Оба варианта написания являются абсолютно правильными. Но, согласитесь, первый покороче. :)

Итак, что такое массивы мы разобрались, теперь надо понять как же с ними работать. Прежде всего надо помнить что такие команды как echo или print выводят только строки и при попытке посмотреть «в массив» они нам выведут просто слово array. Что ж, значит надо использовать какие-то другие операторы. Для данных целей нам подойдут print_r и var_dump.
Оба оператора выводят список ключей и значений массива, но var_dump дает более полную информацию, такую как тип данных в массиве и, например если это строка, её длину. Попробуйте сделать вот так:


<?php

$array 
= array(

'yellow'=>'банан',

'green'=>'яблоко',

'red'=>'томат');

echo 
'<pre>';

print_r($array);

echo 
'<br/>';

var_dump($array);

echo 
'</pre>';

?>

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

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

Часто требуется отсортировать массив под свои требования, для этого хорошо помогает функция *sort, точнее это даже не одна, а целое семейство функций:
rsort — Сортирует массив в обратном порядке
sort — Сортирует массив в порядке позрастания элементов
ksort — Сортирует массив по ключам
krsort — Сортирует массив по ключам в обратном порядке
arsort — Сортирует массив в обратном порядке, сохраняя ключи
asort — Сортирует массив, сохраняя ключи
uasort — Сортирует массив, используя пользовательскую функцию для сравнения элементов с сохранением ключей
uksort — Сортирует массив по ключам, используя пользовательскую функцию для сравнения ключей
usort — Сортирует массив по значениям используя пользовательскую функцию для сравнения элементов.

Приведу примеры работы с несколькими из этих функций:


<?php

$array 
= array(

'yellow'=>'банан',

'green'=>'яблоко',

'red'=>'томат');

ksort($array);

print_r($array);

/*

Вернет

Array

(

    [green] => яблоко

    [red] => томат

    [yellow] => банан

)

*/

?>

Массив отсортирован по ключам. Теперь посмотрим вот это


<?

$array 
= array(

'yellow'=>'банан',

'green'=>'яблоко',

'red'=>'томат');

rsort($array);

print_r($array);

/*

Вернет

Array

(

    [0] => томат

    [1] => яблоко

    [2] => банан

)

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

*/

?>

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


<?php

$array 
= array(

'yellow'=>'банан',

'green'=>'яблоко',

'red'=>'томат');

if(
in_array('томат',$array))

echo 
'Такой элемент присутствует в массиве!';

?>

Так же в своей практике часто встречалсяс тем что надо проверить существует ли ключ в массиве. Это делается при помощи array_key_exists:


<?php

$array 
= array(

'yellow'=>'банан',

'green'=>'яблоко',

'red'=>'томат');

if(
array_key_exists('red',$array))

echo 
'Такой элемент присутствует в массиве!';

else echo 
'Такого элемента нет';

?>

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


<?php

$array 
= array(

'yellow'=>'банан',

'green'=>'яблоко',

'red'=>'томат');

$array2 = array('new','array');

$array3 array_merge($array,$array2);

print_r($array3);

/*

Вернет 

Array

(

    [yellow] => банан

    [green] => яблоко

    [red] => томат

    [0] => new

    [1] => array

)

*/

?>

Так же нужно бывает подсчитать количество элементов массива, для этого подойдет функция count


<?php

$array 
= array(

'yellow'=>'банан',

'green'=>'яблоко',

'red'=>'томат');

print 
count($array); //вернет 3

?>

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

понедельник, 14 сентября 2009 г.

Тайные данные или массив $_SERVER

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

$_SERVER['PHP_SELF']
Данный элемент массива содержит путь к файлу относительно корня сайта, т.е. если адрес до выполняемого скрипта: http://phpbegun.ru/files/script.php данный элемент массива будет содержать в себе /files/script.php.

$_SERVER['DOCUMENT_ROOT']
Содержит абсолютный путь до корневой дирректории сайта, т.е. путь от корня сервера.

$_SERVER['HTTP_HOST']
Содержит имя хоста из текущего запроса сервера.(т.е фактически хост сервера, елси он есть)

$_SERVER['SERVER_ADDR'] Возвращает IP сервера, на котором выполняется скрипт.

;$_SERVER['SERVER_NAME']
Имя (хост) сервера на котором запущен скрипт.

$_SERVER['REQUEST_METHOD']
Тип запроса использованный при оьбращении к скрипту. (например ‘GET’, ‘HEAD’, ‘POST’, ‘PUT’)

$_SERVER['QUERY_STRING']
Строка запроса, т.е. все что находится после вопросительного знака. (http://phpbegun.ru?what=1

$_SERVER[''HTTP_REFERER']
Данный элемент массива, если он существует, показывает нам на какой прошлый адрес, (до обращения к выполняемому скрипту) последний раз обращлся пользователь.

$_SERVER['HTTP_USER_AGENT']
С помощью данного элемента массива можно получить всю информацию о браузере (юзер агенте) пользователя.

$_SERVER['REMOTE_ADDR']
Здесь хранится IP пользователя который обратился к странице.

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

среда, 9 сентября 2009 г.

Защищаемся с помощью htaccess или конфигурация Apache

Очень часто все попытки написать грамотный, хорошо защищенный скрипт сводятся на нет лишь тем что сервер, на котором крутится ресурс неправильно настроен. Или точнее некоторые просто игнорируют настройку сервера как вариант защиты, а это, на мой взгляд абсолютно не приемлимо. "Как же защитить свой ресурс?"-спросите вы,-"Ведь на сервере обыкновенного хостера, нет доступа к доустановке какого либо ПО, или к консоли." (в наше время консоль, к сожалению многих, предоставляют лишь на достаточно дорогих тарифах хостинга). Да, вы правы, если у вас нет консоли доустановить что-либо невозможно. Но вот сконфигурировать apache (web-сервер на котором крутятся очень многие хостинги) вполне в ваших силах с помощью волшебного файлика .htaccess Данный файл конфигурирует apache у вас на хостинге персонально для вас. Конечно, все настройки apache вы изменить не сможете, но в большинстве случаев это и абсолютно не нужно. Надо заметить что htaccess действует не только на ту дирректорию, в которой находится, но и на все каталоги ниже по древу, если конечно в них не лежит свой htaccess. Вот примерно так.

/.htaccess
/cat/.htaccess
/dir/
/dir/vigvam/

Здесь на каталоги dir распространяется действие "корневого" файла htaccess а в каталоге cat он свой. 
Ну что ж...куда класть файл мы примерно разобрались, давайте теперь посмотрим что в нем должно быть. Прежде всего в корневом файле htaccess мы можем назначить страницы ошибок, чтобы выводились наши страницы, а не дефолтные "апачевские".

ErrorDocument 404 http://badcode.net.ru/404/

В примере при ошибке 404 (Not found) будет перекидывать на адрес http://badcode.net.ru/404/
Кроме того в данном файле можно задать по умолчанию индексную страницу, т.е. ту страницу которая будет выводиться если не найдена например index.html или index.php

DirectoryIndex figvam.php

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

Options -Indexes

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

Order Deny,Allow 

Deny from all

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

Order Deny,Allow 

Deny from all

Allow from ip1,ip2

Где, ip1 и ip2 это айпишники с которых дозволен доступ. Но это далеко не весь спектр возможных настроек при помощи htaccess. Данный файл может конфигурировать php (если конечно php настроен на сервере как модуль apache, на большинстве хостингов это именно так). Например включить/отключить глобальные переменные.

php_flag register_globals off #отключили

Так же возможно включить или отключить magic_quotes

php_value magic_quotes_gpc off #отключили

У хорошего программиста пользователь никогда не видит ошибок в скриптах. А сделать это можно например так:

php_value error_reporting 0 # или
php_flag error_reporting 0

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

php_value auto_prepend_file /home/www/user/htdocs/top.php

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

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

вторник, 8 сентября 2009 г.

Учимся ходить

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



Прежде всего, вы должны четко понимать что php-язык серверный, т.е выполняется он целиком и полностью на сервере, генерирует данные которые надо и отдает их пользователю. После того, как данные переданы, их нельзя изменить без повторного обращения к серверу.[caption id="attachment_15" align="alignleft" width="300" caption="Схема Server(php) - пользователь(браузер)"]Схема Server(php) - пользователь(браузер)[/caption]



В чем же в таком случае удобство php? Да в том что его не надо компилировать, в него можно свободно интегрировать другие языки (JavaScript, HTML). Во многих самоучиителях, первым делом, рассматривается простейший вывод данных. Я не буду оригинален и поступлю так же на примере файла hello.php


  echo'Hello World!';
 ?>


Что же это за код? Давайте разберем по порядку. Прежде всего, мы должны дать понять серверу, что обрабатывается php код для этого мы и открываем треугольную скобку со знаком вопроса и надписью php. После вызываем оператор (функцию) вывода строки на экран echo. Ну и дальше идет текст котрый будет выводиться. В нашем случае это 'Hello World!'. Данный текст должен обязательно обрамляться либо одинарными либо двойными кавычками. Какая разница, спросите вы, какие кавычки? Об этом я расскажу в дальнейшем. Окончание действия каждого оператора в php выделяется ; т.е если мы не хотим чтобы действие оператора распространялось на дальнейший код, мы ставим точку с запятой. Ну и в конце мы закрываем нашу треугольную скобку, давая понять машине, что далее ничего интерпритировать не надо. Вот собственно и все. Ваш первый скрипт претворен в жизнь, поздравляю.