Свежие комментарии

    Архивы рубрики ‘PHP’

    Отправка e-mail в русской кодировке средствами PHP

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

    Отправка почты средствами PHP осуществляется при помощи функции mail(),которая имеет следующий синтаксис:

    mail($to, $subject, $body [, $headers] [. $parameters])

    Эта функция принимает следующие аргументы:

    $to — адрес электронной почты получателся;

    $subject — тема сообщении;

    $message — текс сообщении;

    $headers — дополнительные заголовки,которые можно задать в сообщении;

    $parameters — дополнительные параметры,которые можно задать в сообщении.

    Если не указывается четвертый параметр $headers,письмо не снабжается никакими дополнительными почтовыми заголовками.Однако очень часто требуется изменить формат письма с обычного текст (text/plain) на HTML-формат(text/html) или указать кодировку сообщения.

    Установка формата письма и его кодировки осуществляются при помощи почтовых заголовков Content-Type и charset соответственно.

    Content-Type: text/html; charset=KOI8-Rrn

    Для отправки почтового сообщения в кодировке cp1251 вместо KOI8-R следует прописать windows-1251.

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

    <?php
    $theme = "Статистика сайта";
    $theme = convert_cyr_string($theme, 'w', 'k');
    $message = "
    Письмо отправлено - ".date("d.m.Y H:i:s")."
    Размер скрипта отправителя - ".filesize($_SERVER['PHP_SELF'])."
    ";
    $message = convert_cyr_string($message, 'w', 'k');
    $headers = "Content-Type: text/html; charset=KOI8-Rrn";
    if(mail($to, $subject, $message, $headers))
    {echo "Письмо успешно отправлено";}
     else
    {echo "Произошла ошибка - письмо не отправлено";}
    ?>

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

    From: name

    Вместо name указывается имя,которое будет отображаться клиентским почтовым агентом как имя отправителя,а e-mail содержит обратный почтовый адрес.Так,строки формирования переменной $headers могут выглядеть следующим образом:

    <?php
    $headers = "Content-Type: text/html; charset=KOI8-Rrn";
    $headers .="From: server <someone@live-code.ru>rnrn";
    ?>
    </someone@live-code.ru>

    При отправке электронного письма,снабженного почтовыми заголовками,которые были представлены выше,будут представлены как письмо от пользователя server с электронным адресом someone@live-code.ru

    Cookie в PHP

    Здравствуйте уважаемые читатели блога. В этой статье я расскажу о cookie в php.HTTP-протокол,лежащий в основе интернета,не сохраняет информацию о состоянии сеанса.Это означает,что любое обращение клиента сервер воспринимает как обращение нового клиента,и даже если клиент формирует запрос для загрузки картинок с текущей страницы,сервером он воспринимается как запрос нового клиента,никак не связанного с тем,который только что загрузил страницу.

    Данная схема достаточно хорошо работала для статических страниц,но стала совершенно неприемлемой для динамических.В связи с этим в протокол HTTP были введены механизмы cookie,который в настоящий момент поддерживают все участники итернета: клиенты,прокси-серверы и конечные серверы.

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

    Дословно cookie переводится как “кекс” или “сладкий бонус”,выдаваемый клиентам ресторана,чтобы они запомнили его и посетили вторично.Из-за достаточно сумбурного английского названия для cookie так и не было подобрано адекватного перевода.

    Для создание cookie предназначена функция setcookie(),которая имеет следующий синтаксис:

    setcookie($name [, $value [, $expire [, $path [, $domain [, $secure]]]]]

    Функция setcookie принимает следующие аргументы:

    $name – имя cookie;

    $value – значение,хранящееся в cookie с именем name;

    $expire – время в секундах,прошедшее с 0 часов 00 минут 1 января 1970 года.По истечении этого времени cookie удаляется с машины клиента;

    $path – путь,по которому доступен cookie;

    $domain – домен,из которого доступен cookie;

    $secure – директива,определяющая,доступен ил файл cookie на машине клиента и FALSE – в противном случае.После того как cookie установлен,его значение можно получить на всех страницах Web-приложения,обращаясь к суперглобальному массиву $_COOKIE и используя в качестве ключа имя cookie.

    Так как cookie передается в заголовке HTTP-запроса,то вызов функции setcookie() необходимо размещать до начала вывода информации в окно браузера функциями echo(),print() и т.п.,а также до включения в файл HTML-тегов.

    Например: Подсчет количества обращений к странице

    <?php
    // Выставляем уровень обработки ошибок
    error_reporting(E_ALL & ~ E_NOTICE); 
    // Увеличиваем значение cookie
    $_COOKIE['counter']++; 
    // Устанавливаем cookie
    setcookie("counter", $_COOKIE['counter']); 
    // Выводим значение cookie
    echo "Вы посетили эту страницу {$_COOKIE['counter']} раз";
    ?>

    Аутентификация и авторизация пользователя – делаем с нуля (Часть 2)

    Продолжаем работу над нашими скриптами. Работать мы будем в кодировке UTF-8, проверяем кодировку в наших редакторах, в Notepad2 заходим в File -> Encoding -> Выбираем UTF-8, сохраняем страницу как index.php

    1. База данных

    Создаем базу данных, она будет отвечать за данные пользователей.

    База будет называться mysite и в ней таблица users

    CREATE TABLE `users` (
    `id` INT( 5 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `login` VARCHAR( 50 ) NOT NULL ,
    `password` VARCHAR( 50 ) NOT NULL ,
    `log_date` DATETIME NOT NULL ,
    UNIQUE (
    `login`
    )
    ) ENGINE = MYISAM ;

    id — Уникальный идентификатор пользователя

    login — Логин пользователя

    password — Зашифрованный пароль

    log_date — Дата последнего визита

    2. Форма для аутентификации

    Далее нам нужен каркас для страницы аутентификации.

    Сохраняем файл как login_form.html в папку template

    <h2>Аутентификация</h2>
    <form name="form1" method="post" action="">
      <table border="0" cellpadding="0" cellspacing="0" width="245">
        <tbody>
    <tr>
          <td width="101" height="30">Логин</td>
          <td width="144"><input name="login" id="login" type="text"></td>
        
    </tr>
        
    <tr>
          
    <td>Пароль</td>
          
    <td><input name="password" id="password" type="text"></td>
        
    </tr>
        
    <tr>
          
    <td> </td>
          <td align="right"><input name="Submit" value="Вход" type="submit"></td>
        
    </tr>
      </tbody></table>
    </form>

    Получается вот такая форма

    3. Конфигурационный файл

    Чтобы работать с базами данных, нам нужно создать с ней подключение.

    Для этого понадобится три функции mysql_connect(), mysql_select_db(), mysql_close()

    Создаем файл config.php и сохраняем в корень, там где и файл index.php

    <?php
    /* ---------------
    ** Конфигурационный файл
    ** --------------- */
    // Данные для поделючения к базе
    $Config = array(
     "dbhost" => "localhost",  // IP где распаложена база данных
     "dbname" => "mysite",     // Название базы данных
     "dbuser" => "root",       // Пользователь от MySQL
     "dbpass" => "qwerty",     // Пароль от MySQL
    );
    // Подключемся к базе
    $db = mysql_connect($Config['dbhost'], $Config['dbuser'], $Config['dbpass']) or die("Could not connect: ". mysql_error());
    // Выбираем базу с которой мы будем работать
    mysql_select_db($Config['dbname'], $db) or die ("Невозможно подключится к базе {$Config['dbname']}, причина: " . mysql_error());
    // Кодировка базы
    mysql_query("SET NAMES UTF8");
    ?>

    Аутентификация и авторизация пользователя — делаем с нуля (Часть 1)

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

    Сейчас будет небольшой FAQ по работе…

    Для чего нужна авторизация на сайте?

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

    Важна ли безопасность ?

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

    Стоит ли шифровать пароль пользователей ?

    Самая большая ошибка которую можно сделать, это сохранить пароли в базу в своем настоящем виде. Пароль нужно шифровать в таком виде(как пример):

    <?php
    $login = $_POST['login'];  // Логин в данном случае используется как соль
    $pass = $_POST['pass'];  // Пароль пользователя
    $sha_pass = md5(sha1($login.$pass));
    ?>

    Сейчас будет трудно получить пароль, если даже взломать и получить базу сайта. Заметьте «Трудно» а не «Невозможно» любую программу можно взломать, любой код можно расшифровать. Можно но трудно это сделать. Хакер долго будет его угадывать если не знает алгоритм шифрования. А теперь представьте если мы оставим пароль в своем исходном виде, а так хакер скорее всего плюнет и забудет. Берегите своих пользователей

    Начнем работу !

    Для начало нам нужно некоторые программы для работы, точнее только одна

    Текстовой редактор Notepad2

    (Если у вас уже есть привычный редактор пользуйтесь им)

    Необходима знать: HTML, основы PHP, основы-SQL

    PHP функции для работы с массивами

    PHP массивы являются простым способом хранения множества битов информации (например, строк) в простой переменной PHP, известный как «переменная-массив». Доступ к каждой отдельной части информацию можно получить с помощью ключа или индекса.

    С другой стороны, «строки» являются конечным набором символов алфавита. В PHP можно указать строку с одинарных или двойных кавычках:

    <?php
    $string1= 'This is a string created by single quote';
    $string2= "This is a string created by double quotes";
    ?>

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

    <?php
    //создать переменную-массив $planets
    $planets=array();
    //сохранить строки, которые являются названиями планет, в переменной-массиве $planets
    $planets=array("Mercury","Venus","Earth","Mars","Jupiter","Saturn","Uranus","Neptune");
    //вывести в броузер содержимое переменной-массива
    var_dump($planets);
    ?>

    Вывод будет таким:

    array(8) {

    [0]=>string(7) «Mercury»

    [1]=>string(5) «Venus»

    [2]=>string(5) «Earth»

    [3]=>string(4) «Mars»

    [4]=>string(7) «Jupiter»

    [5]=>string(6) «Saturn»

    [6]=>string(6) «Uranus»

    [7]=>string(7) «Neptune»

    }

    Числа от [0] до [7] являются значениями индекса (ключа), которые соответствуют каждой строке, хранящейся в массиве. Строку можно получить при помощи ключа. Предположим, вам необходимо получить планету «Jupiter», ключом будет 4:

    <?php
    var_dump($planets[4]);
    ?>

    Существуют также и «ассоциативные массивы», которые являются полезными, если не используется последовательный числовой индекс (ключ) для элементов строки. Например:

    <?php
    //Пример1. Ассоциативный массив людей и их животных
    $favoritepet=array("Mary"=>"Dog","John"=>"Snakes","Paul"=>"Centipede","Peter"=>"Cat");
    var_dump($favoritepet);
    //Пример2. Ассоциативный массив людей и их вес в килограммах
    $weight=array("Mary"=>50,"John"=>60,"Paul"=>80,"Peter"=>71);
    var_dump($weight);
    ?>

    Далее приведен вывод вышеуказанных массивов

    Пример1:

    array(4) {

    [«Mary»]=>string(3) «Dog»

    [«John»]=>string(6) «Snakes»

    [«Paul»]=>string(9) «Centipede»

    [«Peter»]=>string(3) «Cat»

    }

    Пример2:

    array(4) {

    [«Mary»]=>int(50)

    [«John»]=>int(60)

    [«Paul»]=>int(80)

    [«Peter»]=>int(71)

    }

    <b>Функции для работы с массивами строк</b>

    1. count() это функция, которую можно использовать для подсчета всех элементов, которые присутствуют в массиве. Например:

    <?php
    $nameofgirl= array("Amanda","Jenna","Elizabeth");
    echo "The number of girl names in the array is ".count($nameofgirl);
    ?>

    Результатом будет 3. Существует функция аналогичная count(), известная как SizeOf(), которая дает тот же результат.

    2. Функция array_push() используется при вставке/добавлении новых элементов в существующий массив. Предположим, вы добавите следующие имена Linda,Jenny и Anna в созданную ранее переменную-массив $nameofgirl:

    <?php
    $nameofgirl=array();
    $nameofgirl= array("Amanda","Jenna","Elizabeth");
    //добавить новые имена в существующий массив
    array_push($nameofgirl, "Linda", "Jenny","Anna");
    var_dump($nameofgirl);
    ?>

    А вот вывод (обратите внимание, что новые элементы добавляются в конец массива)

    array(6) {

    [0]=> string(6) «Amanda»

    [1]=> string(5) «Jenna»

    [2]=> string(9) «Elizabeth»

    [3]=> string(5) «Linda»

    [4]=> string(5) «Jenny»

    [5]=> string(4) «Anna»

    }

    Ещё один способ добавить элементы в массив, это приравнять добавляемую строку переменной-массиву:

    $arrayvariable[]=»String to be inserted to the array»

    Добавим пять букв в созданный массив букв алфавита:

    <?php
    $fiveletters=array("d","e","f","e","f");
    $existingarray=array("a","b","c");
    //Считываем массив из пяти букв с помощью цикла и добавляем в существующий массив
    foreach ($fiveletters as $value) {
    $existingarray[]=$value;
    }
    //выводим обновленные элементы в массиве $existingarray
    var_dump($existingarray);
    ?>

    Вот результат:

    array(8) {

    [0]=>string(1) «a»

    [1]=>string(1) «b»

    [2]=>string(1) «c»

    [3]=>string(1) «d»

    [4]=>string(1) «e»

    [5]=>string(1) «f»

    [6]=>string(1) «e»

    [7]=>string(1) «f»

    }

    3. Функция in_array() проверяет, присутствует ли определенная строка в массиве.

    Предположим, необходимо проверить присутствует ли имя «Linda» в массиве $nameofgirl:

    <?php
    $nameofgirl=array();
    $nameofgirl= array("Amanda","Jenna","Elizabeth");
    array_push($nameofgirl, "Linda", "Jenny","Anna");
    //проверяем присутствует ли имя "Linda" в массиве
    if (in_array("Linda",$nameofgirl)) {
    echo "Yes the name Linda is found on the array";
    } else {
    echo "Sorry but the name Linda is not on the array";
    }
    ?>

    Приведенный выше код выводит «Yes the name Linda is found in the array».

    4. Функция array_unique() удаляет из массива повторяющиеся значения.

    Допустим, у нас есть массив цветов:

    <?php
    //Массив цветов, элемент "red" повторяется
    $fivecolors=array("blue","red","yellow","red","magenta");
    var_dump($fivecolors);
    ?>

    Ниже приведен дамп этого массива (обратите внимание на значение индекса (ключа) каждого элемента строки):

    array(5) {

    [0]=>string(4) «blue»

    [1]=>string(3) «red»

    [2]=>string(6) «yellow»

    [3]=>string(3) «red»

    [4]=>string(7) «magenta»

    }

    Теперь удалим дубликаты с помощью функции array_unique:

    <?php
    $fivecolors=array("blue","red","yellow","red","magenta");
    //удаляем повторяющиеся значения в массиве
    $unique=array_unique($fivecolors);
    //выводим в броузер
    var_dump($unique);
    ?>

    Далее приведен дамп результатов работы функции array_unique. Обратите внимание, что элемент с индексом 3 исчез, поскольку является дубликатом.

    array(4) {

    [0]=>string(4) «blue»

    [1]=>string(3) «red»

    [2]=>string(6) «yellow»

    [4]=>string(7) «magenta»

    }

    5. Функция array_values() используется для устранения любых разрывов в индексах, вызванных выполнением array_unique. В предыдущем примере, вы можете заметить значения индексов 0,1,2 и 4 (3 удален, потому что является дубликатом). Порядок индексов можно восстановить в 0,1,2,3,4 с помощью функции array_values():

    <?php
    $fivecolors=array("blue","red","yellow","red","magenta");
    $unique=array_unique($fivecolors);
    //восстанавливает нумерацию индексов, удаляя разрывы в последовательности
    $resettedindex= array_values($unique);
    //вывод в браузер
    var_dump($resettedindex);
    ?>

    Будет выведено:

    array(4) {

    [0]=> string(4) «blue»

    [1]=> string(3) «red»

    [2]=> string(6) «yellow»

    [3]=> string(7) «magenta»

    }

    Теперь индексы имеют правильную последовательность (0,1,2,3)

    6. Функция array_change_key_case() может быть использована для приведения всех элементов в массиве к единому регистру. Иногда вы будете обрабатывать в массиве строковые элементы, которые не имеют единого регистра (например, строки с верхнем и нижнем регистре). Если вам нужно сделать все строки «в верхнем регистре» или «в нижнем регистр», то можете использовать эту функцию.

    <?php
    $mixedcase=array("bLuE"=>1,"RED"=>2,"Yellow"=>3,"mAgENTA"=>4);
    //Преобразовать все строки в массиве в верхний регистр
    $uppercase= array_change_key_case($mixedcase, CASE_UPPER);
    //вывести содержимое массива
    var_dump($uppercase);
    ?>

    Вывод:

    array(4) {

    [«BLUE»]=>int(1)

    [«RED»]=>int(2)

    [«YELLOW»]=>int(3)

    [«MAGENTA»]=>int(4)

    }

    Примечание: Если не указать CASE_UPPER, то по умолчанию будет использоваться нижний регистр.

    7. Функция array_count_values возвращает частоту появления элементов в массиве. Пример:

    <?php
    $fivecolors=array("blue","red","yellow","red","magenta");
    //возвращает частоту появления элементов
    $frequency=array_count_values($fivecolors);
    var_dump($frequency);
    ?>

    При этом будет выведен следующий результат:

    array(4) {

    [«blue»]=>int(1)

    [«red»]=>int(2)

    [«yellow»]=>int(1)

    [«magenta»]=>int(1)

    }

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

    <?php
    $fivecolors=array("blue","red","yellow","red","magenta");
    $frequency=array_count_values($fivecolors);
    //возвращает частоту появления только красного цвета
    echo $frequency["red"];
    ?>

    8. Функция array_search будет искать данную строку в переменной-массиве и возвращать индекс, если он найден. Пример:

    <?php
    $fivecolors=array("blue","red","yellow","magenta");
    //Ищет синий цвет и возвращает ключ
    $key = array_search('blue', $fivecolors);
    echo $key;
    ?>

    Результатом будет 0, поскольку синий (blue) является первым элементом массива. Ещё пример:

    <?php
    $fivecolors=array("blue","red","yellow","magenta");
    //Ищет белый цвет и возвращает ключ
    $key = array_search('white', $fivecolors);
    echo $key;
    ?>

    Результатом будет False/Null или логический 0, потому что белый цвет не входит в массив. Имейте в виду, что 0 может быть результатом двух возможных сценариев: в первом случае цвет действительно существует в массиве, и находится в первом элементе. Во втором сценарий функция array_search не может найти строку в массиве и возвращает то, что может быть интерпретировано как 0/False или null.

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

    <?php
    $fivecolors=array("blue","red","yellow","red","magenta");
    //Найти белый цвет и вернуть ключ
    //Проверить, что белый цвет присутствует в массиве
    if (in_array("white",$fivecolors)) {
    //белый цвет есть в массиве, теперь получить ключ
    $key = array_search('white', $fivecolors);
    echo $key;
    } else {
    //белого цвета нет в массиве
    echo "The key does not exist for this color";
    }
    ?>

    9. Функция asort сортирует строковые элементы переменной- массива в алфавитном порядке и поддерживает соответствующий индекс.

    <?php
    $favoritebands=array("Mary"=>"Nirvana","John"   =>"Metallica","Paul"=>"Beatles","Peter"=>"Who","Alice"=>"Greenday","Chris"=>"Black   Sabbath");
    foreach ($favoritebands as $key => $val) {
    echo "$key = $val<br />";
    }
    ?>

    Результат (без сортировки)

    Mary = Nirvana

    John = Metallica

    Paul = Beatles

    Peter = Who

    Alice = Greenday

    Chris = Black Sabbath

    Сортировка элементов массива по именам групп:

    <?php
    $favoritebands=array("Mary"=>"Nirvana","John"   =>"Metallica","Paul"=>"Beatles","Peter"=>"Who","Alice"=>"Greenday","Chris"=>"Black   Sabbath");
    //сортирует строковые элементы и поддерживает ассоциацию с индексом
    asort($favoritebands);
    foreach ($favoritebands as $key => $val) {
    echo "$key = $val<br />";
    }
    ?>

    Теперь отсортированный результат:

    Paul = Beatles

    Chris = Black Sabbath

    Alice = Greenday

    John = Metallica

    Mary = Nirvana

    Peter = Who

    10. array_merge объединяет элементы двух и более массивов

    <?php
    $fivecolors=array("blue","red","yellow","magenta");
    $threecolors=array("white","black","green");
    //Объединить два массива
    $eightcolors=array_merge($fivecolors,$threecolors);
    var_dump($eightcolors);
    ?>

    Результат:

    array(7) {

    [0]=>string(4) «blue»

    [1]=>string(3) «red»

    [2]=>string(6) «yellow»

    [3]=>string(7) «magenta»

    [4]=>string(5) «white»

    [5]=>string(5) «black»

    [6]=>string(5) «green»

    }

    11. Функция array_pop извлекает последний элемент из массива. Это полезно, когда необходимо удалить последний элемент из массива:

    <?php
    $animals=array("bear","lion","cheetah","tiger","wolf");
    //удаляем последний элемент
    $pop_out = array_pop($animals);
    //показать удаленный элемент
    var_dump($pop_out);
    //вывести обновленный массив animals
    var_dump($animals);
    ?>

    Вывод для последнего удаленного элемента:

    string(4) «wolf»

    Вывод обновленного массива animals (элемента wolf нет, он был удален из массива)

    array(4) {

    [0]=>string(4) «bear»

    [1]=>string(4) «lion»

    [2]=>string(7) «cheetah»

    [3]=>string(5) «tiger»

    }

    Проверенные способы защиты PHP

    Проверенные способы защиты PHP

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

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

    Защита PHP с помощью php.ini

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

    Запретить Register Globals

    До версии 4.2.0, PHP использовал глобальные переменные для предоставления доступа к входным переменным из запросов GET и POST. Эта функция была ликвидирована, поскольку она обеспечивает лазейку в безопасности. Злоумышленники могут использовать его для управления переменными в рамках различных сценариев. Но для обеспечения обратной совместимости PHP позволяет настраивать register_globals в php.ini. Когда эта опция включена, PHP работает в старом режиме и регистрирует глобольные переменные для входных значений. Чтобы обеспечить безопасность PHP, всегда следует выключать эту настройку. Избегайте использования сценариев, которым требуется register_globals, поскольку это обычно является признаком потенциально опасных или редко обновляемых сценариев.

    Управление доступом к файлам

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

    Хотите начать зарабатывать, продвигая свой аккаунт в социальных сетях и используя интернет маркетинг, но не знаете с чего начать? Сайт прайссмм поможет Вам разобраться в таком процессе. Здесь молодой, но достаточно опытный специалист расскажет Вам о том, чего многие до сих пор не знают. Это поможет Вам достаточно быстро поднять рейтинг любой страницы, аккаунта или канала.

    Один из вариантов, который можно использовать в php.ini это open_basedir. Данный параметр принимает в качестве значения подкаталог, такой как /home/user/html/. Ввод/вывод интерпретатора ограничивается указанным подкаталогом, что предотвращает чтение и запись файлов за пределами данного подкаталога с помощью PHP.

    Вы можете также использовать параметр safe_mode в php.ini для управления доступом к файлам. В безопасном режиме PHP способен открывать только те файлы, которые принадлежат тому же пользователю, что и веб-сервер. Настройка также предотвращает запуск исполнимых файлов с помощью PHP. Если нужно разрешить PHP доступа к файлам, которые принадлежат разным владельцам, можно использовать safe_mode_gid. Параметр ограничивает доступ в PHP только теми файлами, которые принадлежат группе, под которой работает веб-сервер.

    Сокрытие PHP

    Хотя обеспечения безопасности путем внесения неясности недостаточно для защиты приложения, это усложнит попытки взлома, поскольку хакеры не будут знать, какие технологии вы используете. PHP выдает себя по ряду признаков, среди которых заголовки и подпись Apache. Это можно отключить с помощью expose_php = off в php.ini.

    Ещё один признак, который выдает PHP, это отображение ошибок. Ошибки часто включают в себя информацию о путях и других параметрах, которую хакер найдет неоценимой. Сообщения об ошибках являются бесценными в процессе разработки для тестирования и отладки, но они должны быть выключены при введении приложения в эксплуатацию. Вы можете их отключить, установив: display_errors = Off в php.ini. Полезной функцией является запись сообщений об ошибках в лог-файл, которую можно включить, установив: log_errors = On в php.ini.

    Наконец, можно настроить Apache для перезаписи URL, чтобы скрыть расширение PHP.

    Использование проверенных методов программирования

    После обеспечения безопасности PHP настройкой php.ini, необходимо обратить внимание на сам код. Другим методом защиты PHP является хорошая техника программирования. Есть целый ряд проверенных методов программирования, но не меньше методик, которые нужно избегать.

    Контроль POST и передачи форм

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

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

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

    Защита баз данных

    При работе с базами данных вы не должны использовать динамические SQL операторы, которые основаны на пользовательском вводе. Это создает реальную возможность для злоумышленников направить неправильные данные в базу данных. Иногда вы должны использовать вводимые пользователем данные в запросе SQL. Проверяйте введенные пользователем данные, прежде чем использовать их в запросе. Если база данных MySQL, вы можете использовать функцию mysql_real_escape_string(). Эта функция удалит недопустимые символы, эффективно обрабатывая пользовательский ввод. Если ваш код использует PHP функциональность magic_quotes_gpc, сейчас самое время пересмотреть назначение кода. Использование magic_quotes_gpc будет прекращено в PHP версии 6.

    Методы кэширования данных на PHP

    Методы кэширования данных на PHP

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

    Статические локальные переменные

    Быстрым и эффективным способом кэширования результатов функции/метода является использование статических локальных переменных. Рассмотрим пример, который выполняет сложные вычисления:

    <?php
    function getValue() {
        static $value;
        if (is_null($value)) {
            $value = ...; // Вычисление
        }
        return $value;
    }
    ?>

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

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

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

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

    Функции разделяемой памяти APC

    PHP является полу-компилируемым языком, а это значит, что каждый сценарий компилируется непосредственно не в машинный код, а в промежуточный код, известный как набор опкодов(байт-код). Данный шаг компиляции потребляет много ресурсов процессора и должен выполняться каждый раз при выполнении сценария. APC (Alternative PHP Cache) это расширение, которое пропускает этот шаг компиляции за счет кэширования опкодов в памяти.

    Хотя основным назначением APC обычно считается функциональность кэширования опкодов, расширение также включает некоторые дополнительные функции доступа к памяти.

    <?php
    function getCurrencyRates() {
        $rates = apc_fetch('rates');
        if (empty($rates)) {
            // Запрос к базе данных или внешним API функциям
            $rates = ...;
            // Курс обмена будет кэширован на 1 час 
            apc_store('rates', $rates, 3600);
        }
        return $rates;
    }
    ?>

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

    Чтобы сделать кэш недействительным, можно использовать значения продолжительности существования (TTL), как в примере выше, или следующие функции:

    <?php
    apc_delete('rates');        // Удаляет кэш $rates 
    apc_clear_cache('user');    // Удаляет все переменные кэша для user 
    ?>

    Другие примечания по поддержке разделяемой памяти в APC:

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

    • С точки зрения производительности — статические переменные всегда будет быстрее, чем функции apc_fetch/apc_store , поскольку доступ к разделяемой памяти должен быть заблокирован и синхронизирован, чтобы предотвратить конфликтные ситуации.

    • APC является довольно популярным расширением, и поддерживается основными разработчиками PHP и (весьма вероятно) будет поставляться в комплекте с PHP 5.4.

    Memcached для больших распределенных кэшей

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

    Memcached с другой стороны, представляет собой распределенную службу для хранения данных ключ-значение. Расширение может быть развернуто на отдельном выделенном сервере или в том же стеке PHP приложений. Важно понимать, что нет никакой синхронизации/репликации между несколькими Memcached серверами, и они совсем ничего не знают друг о друге. Фактический сервер, который будет использоваться для хранения, выбирается на стороне клиента с помощью алгоритма хеширования на основе предоставленных данных «ключа». Именно поэтому, в отличие от APC, кэшированные данные не дублируются между различными машинами, а память лучше используется для крупных распределенных приложений.

    API очень похож на функциональность разделяемой памяти в APC. Тот же пример с обменом валют, реализованный с помощью PHP расширения Memcache:

    <?php
    // Предполагаем, что есть только одна служба memcached 
    $memcache = new Memcache();
    $memcache->pconnect('...');
    function getCurrencyRates() {
        global $memcache;
        $rates = $memcache->get('rates');
        if ($rates === false) {
            // Запрос к базе данных или внешним API функциям
            $rates = ...;
            // Курс обмена будет кэширован на 1 час 
            $memcache->set('rates', $rates, 0, 3600);
        }
        return $rates;
    }  
    ?>

    Обновление кэша такое же, как и в APC – с использованием TTL функциональности или набора функций.

    <?php
    $memcache->delete('rates'); // Удаляет кэш $rates 
    $memcache->flush();         // Удаляет все кэшированные данные
    ?>

    Локальный APC кэш всегда будет более быстрым методом по сравнению с Memcached.

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

    Таблицы баз данных в оперативной памяти

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

    MySQL предоставляет таблицы в оперативной памяти в подсистеме хранения данных MEMORY. Хотя данные будут очищены после перезагрузки сервера — схемы таблиц будут сохраняться:

    CREATE TABLE test (…) ENGINE = MEMORY

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

    CREATE TEMPORARY TABLE test (…)

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

    <?php
    $pdo = new PDO(
        'sqlite::memory:',
        null,
        null,
        array(PDO::ATTR_PERSISTENT => true)
    );
    ?>

    Так что же можно сделать с таблицей в оперативной памяти? Хотя такая таблица никогда не будет быстрее доступа к данным ключ-значение в APC/Memcached, вы получаете мощь SQL. Кэшированные данные могут быть отфильтрованы, упорядочены, сгруппированы и даже объединены с другими данными в таблицах.

    Простой файловый кэш

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

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

    <?php
    // Устанавливаем монопольную блокировку при записи
    file_put_contents('...', $data, LOCK_EX);
    // Используем разделяемую блокировку для чтения 
    $fp = fopen('...', 'r');
    flock($fp, LOCK_SH);
    $data = stream_get_contents($fp);
    flock($fp, LOCK_UN); // Снимаем блокировку
    fclose($fp);
    ?>

    Объявление и вызов функции PHP

    Функция объявляется при помощи ключевого слова function,после которого следует имя функции,в круглых скобках параметры функции и в фигурных скобках записываются различные операторы,составляющие тело функции:

    function MyFunction()

    {

    // операторы

    }

    Если функция возвращает какое-либо значение,в теле функции обязательно должен присутствовать оператор return:

    function MyFunction()

    {

    // Вычисления

    return $mow; // возвращается значение переменной $mow

    }

    Рассмотрим достаточно простой пример:

    <?php
    function get_sum()
     {
      $sum = 25 + 10;
      return $sum;
     }
      echo get_sum(25, 10); // выводит 35
    ?>

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

    Модифицируем эту функцию так,чтобы она не возвращала полученный результат,а выводила его в браузер.Для этого достаточно внести конструкцию echo в тело функции.

    Рассмотрим пример фукции get_sum когда сама выводит результат в браузер:

    <?php
    function get_sum()
     {
      $sum = 25+10;
      echo $sum;
     } get_sum();
    ?>

    Во многих языках программирования функция не может вызываться до ее объявления.В PHP отсутствую подобные ограничения.

    Вызов может осуществляться до объявления функции

    <?php
     get_sum();
     function get_sum()
      {
       $sum = 25 + 10;
       echo $sum;
      }
    ?>

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

    Условное объявление функции

    <?php
    // Объявляем логическую переменную
    $mow = TRUE;
    // Вызываем функцию,если переменная $mow равна TRUE
    if($mow) get_sum(); //Ошибка
    // Если переменная $mow равна TRUE объявляем функцию
    if($mow)
    {
    function get_sum()
    {
    $sum = 25 + 10;
    echo $sum;
    }
    }
    ?>

    Попытка вызова функции,обьявленной условно раньше обьявления,приводит к генерации ошибки:

    Fatal error : Call to undenfined function get_sum() in D:myindex.php on line 7

    PHP загрузка файла на сервер

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

    <input type="file">

    Помимо атрибута type,элемент управления допускает указание атрибутов name и size.Простая форма для отправки файла на сервер демонстрируется ниже:

    HTML-форма для загрузки файлов на сервер — index.html

    <h2><b> Форма для загрузки файлов </b></h2>
      <form action="upload.php" method="post" enctype="multipart/form-data">
      <input name="filename" type="file">
      <input value="Загрузить" type="submit">
      </form>

    Атрибут enctype формы определяет вид кодировки,которую браузер применяет к параметрам формы.Для того чтобы отправка файлов на сервер действовала,атрибуту enctype необходимо присвоить значение multipart/form-data.По умолчанию этот атрибут имеет значение application/x-www-form-urlencoded.

    После того как получен HTTP-запрос,содержимое загруженного файла записывается во временный файл,который создается в каталоге сервера,заданном по умолчанию для временных файлов,если другой каталог не задан в файле php.ini(директива upload_tmp_dir).

    Характеристики загруженного файла доступны через двумерный суперглобальный массив $_FILES.При этом переменная со значением этого массива может иметь следующий вид:

    — $_FILES[‘filename’][‘name](содержит исходное имя файла на клиентской машине);

    — $_FILES[‘filename’][‘size’](содержит размер загруженного файла в байтах);

    — $_FILES[‘filename’][‘type’](содержит MIME-типа файла);

    — $_FILES[‘filename’][‘tmp_name’](содержит имя временного файла,в который сохраняется загруженный файл).

    Проверить успешность загрузки файла на сервере можно при помощи специальной функции is_upload_file(),которая принимает в качестве единственного параметра имя файла ($_FILES[‘filename’][‘name’]) и возвращает TRUE в случае успешной загрузки и FALSE в случае неудачи.

    Ниже приведен скрипт upload.php,который загружает файл на сервер и копирует его из временного каталога в каталог temp/.

    <?php
     if(copy($_FILES['filename']['tmp_name'],
        "temp/".$_FILES['filename']['name']))
     {
      echo "Файл успешно загружен";
     }
     else
     {
       echo "Ошибка загрузки файла";
     }
    ?>

    После выполнения этого скрипта выбранный для загрузки файл будет помещен в подкаталог temp каталога,в котором расположен скрипт,а браузер выдаст фразу «Файл успешно загружен».

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

    <strong>Характеристики файла</strong>
    <?php
       if(copy($_FILES['filename']['tmp_name'],
        "temp/".$_FILES['filename']['name']))
     {
      echo "Файл успешно загружен 
    <";
      // Далее выводится информации о файле
      echo "Характеристики файла: 
    ";
      echo "Имя файла: ";
      echo $_FILES['filename']['name'];
      echo "
    Размер файла: ";
      echo $_FILES['filename']['size'];
      echo "
    Каталог для загрузки: ";
      echo $_FILES['filename']['tmp_name'];
      echo "
    Тип файла: ";
      echo $_FILES['filename']['type'];
     }
     else
     {
      echo "Ошибка загрузки файла";
     }
    ?>

    В некоторых случаях требуется ограничить размер файла,который может быть загружен на сервер.К примеру,чтобы зазрешить загрузку на сервер файлов размером не более 4Мбайт,нужно скрипт так,как это представлено ниже:

    Ограничение размера загружаемого файла

    <?php
     if($_FILES['filename']['size'] > 4*1024*1024)
     {
      exit "Размер файла превышает три мегабайта";
     }
    if(copy(_FILES['filename']['tmp_name'],
      "temp/".$_FILES['filename']['name']))
     {
      echo "Файл успешно загружен 
    ";
     }
     else
     {
      echo "Ошибка загрузки файла";
     }
    ?>

    Максимальный размер загружаемого файла можно также задать при помощи директивы upload_max_filesize,значение которой по умолчанию равно 2 Мбайт:

    if($_FILES[‘filename’][‘size’] > upload_max_filesize)

    Значение директивы upload_max_filesize можно изменить в конфигурационном файле php.ini.

    PHP: Постраничная навигация — вывод данных с использованием массива

    PHP: Постраничная навигация - вывод данных с использованием массива

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

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

    Посмотрим на код, в котором показано как это можно сделать.

    <?php
    // Данные, обычно из текстового файла или другого источника    
    $data = "Item 1|Item 2|Item 3|Item 4|Item 5|Item 6|Item 7|Item 8|Item 9|Item 10";   
    // Записываем данные в массив    
    $dataArray = explode('|', $data);   
    // Получаем текущую страницу   
    $currentPage = trim($_REQUEST[page]);   
    // Настройки разбиения на страницы   
    $perPage = 3;   
    $numPages = ceil(count($dataArray) / $perPage);   
    if(!$currentPage || $currentPage > $numPages)   
        $currentPage = 0;   
    $start = $currentPage * $perPage;   
    $end = ($currentPage * $perPage) + $perPage;   
    // Нужные страницы    
    foreach($dataArray AS $key => $val)   
    {   
        if($key >= $start && $key < $end)   
            $pagedData[] = $dataArray[$key];   
    }
    ?>

    Для начала я создал массив $data, который содержит длинный набор элементов, разделенных символом вертикальной черты ‘|’. Элементы приведены в качестве примера, массив должен содержать реальные данные. Затем с помощью функции explode() я разбил переменную $data на массив, используя ‘|’ в качестве разделителя.

    Строка 6 просто получает номер текущей страницы, если он передан.

    Строки с 8 по 13 выполняют математические расчеты, которые требуются, чтобы разбиение на страницы работало. Сначала мы устанавливаем количество элементов, отображаемых на странице, в переменной $perPage. В вышеприведенном примере я установил данное значение равным 3.

    В строке 9 мы просто выясняем, сколько страниц должно быть. Это можно сделать путем деления общего количества элементов (с помощью функции count()) на количество элементов на странице. Обратите внимание, что в этой строке я также использую функцию ceil(). Функция просто округляет число до большего целого (например, 5,134 становится 6).

    В строках 10 и 11 находится простой условный оператор, который устанавливает в 0 номер страницы, если он не был передан или номер страницы больше общего количества страниц. Это предотвращает доступ к страницам, для которых нет элементов.

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

    В строках 12 и 13 устанавливаем переменные $start и $end, которые вы могли узнать, если работали с SQL запросами раньше. Переменные $start и $end содержат наименьший и наибольший идентификатор элемента, который должен отображаться на данной странице.

    Теперь в строке 15 обрабатываем каждый элемент данных в цикле foreach. Внутри цикла условный оператор проверяет, что идентификатор текущего элемента данных больше или равен значению $start и меньше значения $end. Если условие выполняется, то записываем копию элемента в массив $pagedData.

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

    <?php
    foreach($pagedData AS $item)   
        echo $item . "<br>";
    ?>

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

    <?php
    if($currentPage > 0 && $currentPage < $numPages)   
        echo '<a href="?page=' . ($currentPage - 1) . '">« Предыдущая страница</a><br>';   
    if($numPages > $currentPage && ($currentPage + 1) < $numPages)   
        echo '<a href="?page=' . ($currentPage + 1) . '" class="right">Следующая страница »</a><br>';
    ?>

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

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

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

    Просто, не так ли? Это всё, что нужно сделать, чтобы простое разбиение страниц на PHP работало.