My:PHP

Материал из synset
Перейти к: навигация, поиск

Введение

На локальной машине устанавливаем сервер, PHP, SQL при помощи http://www.denwer.ru/. В директорию WebServers/home/localhost/www/newproject помещаем файл test.php:

 
<html><head></head><body>
   <?php  echo("It's PHO<br>"); ?>
</head></html>

В браузере пишем http://localhost/newproject/test.php

То, что находится между <?php ... ?> является php-программой. Любое количество таких вставок может находится внутри html-разметки. Запуская в браузере этот файл (он должен иметь расширение php, а не html!), получаем результат.

Скрипт php можно использовать для обработки посылки полей формы. Пусть в директории WebServers/home/test1.ru/ находятся файлы: www/index.html и cgi/form.php Поместим в index.html форму с двумя полями ввода и кнопкой посылки:

 
<form action = "../cgi/test.php" method="get">
Field1: <input type="text" name="F1"/> <br>
Field2: <input type="text" name="F2"/> <br>
<input type="submit"/>
</form>

Обработка посылки запроса /cgi/form.php?F1=aaa&F2=bbb файлом form.php выглядит так:

 
#!/usr/bin/php 
<?php
   echo("F1 = $_GET[F1]<br>");
   echo("F2 = $_GET[F2]<br>");
   $res = (int)$_GET[F1]+(int)$_GET[F2]
   for($i=1; $i<=$res; $i++ )
      echo("$i <br>");  
?>

Если запрос выполняется при помощи метода POST, то поля находятся в массиве $_POST. В начале php-файла находится путь к интерпретатору. Его надо указывать, если php-файл расположен в отдельной cgi-директории. Если же он в той же директории, что и html-файл, то не надо. (?)

Основы

  • Код php программы находится внутри блока между символами <?php и ?>. Дальше их обычно пропускаем. Можно php не писать, если это указано в настройках PHP (файл php.ini)
  • После <?php ... ?> можно вставлять html разметку и снова начинать програму на php. Когда PHP встречает закрывающие теги ?>, он выводит все, что он находит до следующего открывающего тега. Это удобно для вывода больших блоков текста.
  • Комментарии как в С++. Строчный комментарий также можно начинать с решетки #.
  • Между блоками php программы можно вставлять <!-- комментарий HTML -->. Он будет виден в исходнике html-страницы, но не будет отображаться в браузере.
  • Основной синтаксис (if, for, while, switch) совпадает с C++.
  • Константы задаются функцией: define(PI, 3.141592); define(HI,"Hello"); Имена констант принято отображать заглавными буквами. Логическая функция defined("PI"); проверяет определена ли константа с таким именем.
  • Тип переменных не объявляется, но подразумеваются следующие типы integer, string, boolean, double , array, object; Вызов echo(gettype($var)); печатает тип переменной.
  • Преобразование типов: $var = (int)$var;
  • Так как в языке одна и та же переменная по ходу дела может изменять свой тип, кроме стандартного оператора сравнения "==" существует сравнение "===" и не равенство "!==" значения и типа. Т.е. $a===$b равно true, если $a равно $b и имеет тот же тип.

Строки

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

  • Строка может быть определена: 1) одинарными кавычками 2) двойными кавычками.

Для использования одинарной кавычки внутри строки пишем \'. Внутри одинарных ковычек можно использовать двойные. Можно также использовать 3) heredoc-синтаксис:

 
$str = <<<EOD
Пример строки,
охватывающей несколько строчек.
EOD;

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

 
   echo "var=$var<br>\n";
  • Контатация сторок
 
   $a = "Hello ";
   $b = $a . "World!"; // $b содержит строку "Hello World!"
  • В случае, если целое число сравнивается со строкой, то строка будет преобразована к числу. Поэтому 1=="01", 0=="a" равны true.
  • Инкрементация строки
 
   $i = 'W';
   for($n=0; $n<6; $n++) echo ++$i . ",";

выдаст: X,Y,Z,AA,AB,AC

  • Форматирование чисел
 
   echo number_format( $myNumber, 1 );           // Выводит "123,456.8"
   echo number_format( $myNumber, 2, '.', '' );  // Выводит "123456.78"
  • Разбиение строки на поля:
$lst  = explode("/",'2000/05/27');    //$lst[0] = 2000, $lst[1] = 5, $lst[2] = 27

Массивы

  
   $arr[0]=1;  $arr[1]=2;             // простой массив

   $names["key1"] = "value1";         // ассоциативный массив типа map(ключ-значение)
   $names["key2"] = "value2";
   foreach ($names as $k => $v)       // распечатываем ассоциативный массив
      echo "$k: $v <br>";

   $lst[] = "aaa";                    // список
   $lst[] = "bbb";
   foreach ($lst as $v) {
      echo "<b>$v</b><br>";

   $arr = array(1, 2, 3, 4);
   foreach ($arr as &$v) $v = $v * 2; // $arr is now array(2, 4, 6, 8)

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

Операторы для работы с массивами PHP:

  
$a = array("a" => "aaa", "b" => "bbb");
$b = array("a" => "ddd", "b" => "eee", "c" => "ccc");

$c = $a + $b;        // Объеденение $a и $b ("ddd" и "eee" не появятся, а "ccc" добавится)
var_dump($c);        // вывод массива

var_dump($a === $b); // сравнение массивов (обычное == не применимо!)

Сортировка

Сортировка массива-списка:

  
$fruits = array("lemon", "orange", "banana", "apple");
sort($fruits);  // сортировка по алфавиту. В обратном порядке: rsort 
reset($fruits); // Установить внутренний указатель массива на его первый элемент
while (list($key, $val) = each($fruits))
    echo "fruits[" . $key . "] = " . $val . "\n";

Сортировка хеш-таблицы:

  
$fruits = array("d"=>"lemon", "a"=>"orange", "b"=>"banana", "c"=>"apple");
ksort($fruits);  // сортировка по ключу. По значению: asort. В обратном порядке krsotr, arsort.
reset($fruits);  // Установить внутренний указатель массива на его первый элемент
while (list($key, $val) = each($fruits))
    echo "$key = $val";

Сортировка таблицы:

  
function by_col($a, $b) 
{  
   $col = 0;
   if ($a[$col] == $b[$col])  return 0;
   return ($a[$col] < $b[$col]) ? -1 : 1;
}

$table[] = array("a", "1");
$table[] = array("c", "3");
$table[] = array("b", "2");
usort($table, "by_col");               // сортируем
foreach ($table as $ln)                // выводим поля файла
   echo "$ln[0], $ln[1]<br>\n";

Дата и время

int strtotime ( string time [, int now] ) -- Преобразует текстовое представление даты на английском языке в метку времени Unix (Начало отсчёта - 00:00 (по UTC) 1 января 1970 года («эра UNIX»)):
 
echo strtotime("now"), "\n";                             // 1316202312 (для 2011-09-16 22:45)
echo strtotime("4 September 1966"), "\n";                // -104983200
echo strtotime("+1 day"), "\n";
echo strtotime("+1 week"), "\n";
echo strtotime("+1 week 2 days 4 hours 2 seconds"), "\n";
echo strtotime("next Thursday"), "\n";
echo strtotime("last Monday"), "\n";
echo strtotime("20110904 last Monday"), "\n";

Функция time() даёт текущее UNIX-время. Произвольное время можно получить также функцией:

 
int mktime(int hour, int minute, int second, int month, int day, int year, int [is_dst] ); 

Преобразование UNIX-времени в строку (см. форматы):

 
echo date("Y-m-d H:i:s", strtotime("now")); // в сторку yyyy-mm-dd hh:mm:ss

Доступ к конкретным полям можно получить:

 
$tm = strtotime("2011-08-31 00:00:00");                     // UNIX-время

$arr = getdate($tm);                                        // разбиваем на массив
$h = $arr['hours']; $i = $arr['minutes']; $s = $arr['seconds']; 
$m = $arr['mon'];   $d = $arr['mday'];    $Y = $arr['year'];

echo date("Y-m-d H:i:s", $tm), "<br>\n"; 
echo $Y,"-",$m,"-",$d, " ", $h,": ", $i, ":", $s, "<br>\n";
echo date("Y-m-d H:i:s", mktime($h+24, $i, $s, $m, $d+31, $y)), "<br>\n";  // добавляем 32 !!! дня

Работа с датой при помощи классов:

 
$dt = new DateTime("2011-09-16"); 
echo $dt->format("Y-m-d"), "<br>\n";

$dt->setDate(1966, 9, 4);            // Y,m,d
$dt->setTime(16, 55, 66);            // H,i,[s]

Внимание! Переменная класса является указателем. Поэтому, если необходимо использовать независимую переменную то надо использовать директиву clone:

 
  $now   = new DateTime;
  $clone = clone $now;              // !!!   
  $clone->modify( '-1 day' );
  echo $now->format( 'Y-m-d' ), "<br>\n", $clone->format( 'Y-m-d' );

Если не сделать clone, а присвоить $clone = $now;, то поменяются обе переменные.

Тип DateInterval

  $d1   = new DateTime("1966-09-04");
  $d2   = new DateTime("2011-09-16");
 
  $diff = $d1->diff($d2);                 // тип  DateInterval. Имеет поля: y, m, d, h, i, s

  echo $diff->y,   "<br>\n";               // 45 число лет
  echo $diff->m,   "<br>\n";               //  0 число месяцев
  echo $diff->d,   "<br>\n";               // 12 число дней

Функции

 
function Add($x, $y)
{
   return (int)$x + (int)$y;
}
  • Если внутри функции есть строка "global $var;" это означает, что переменная $var объявлена как глобальная и будет видна во всех других функциях. В отличие от этого остальные переменные имеют локальную область видимости. Доступ к глобальным переменным можно также получить через массив $GLOBALS["var"]).
  • Объявление "static $state = 0;" означает, что значение переменной будет сохраняться при следующих вызовах функции (а начальное задаётся при первом вызове). Однако, если страница перегружается, жизнь этих переменных начинается заново.
  • Внимание! внешние к функции переменные, даже объявленные выше, в функции не видны.
  • В функциях можно использовать рекурсию.

Значения аргументов по-умолчанию:

 
  function makecup($type = "Чая")
  {
     return "Сделайте чашечку $type.\n";
  }
  echo makecup();
  echo makecup("Кофе");

Аргументы можно передавать по ссылке. Их изменение внутри функции будет "видно" наружу:

 
function Inc(&$var) // аргумент передается по ссылке
{
  return ++$var;
}

Возвращение значения по ссылке:

 
   function &returns_reference(){ return $someref; }
   $newref =& returns_reference();

Возвращение функцией массивов:

  
   function numbers(){  return array (0, 1, 2); }
   list ($zero, $one, $two) = numbers();
   echo $zero;

Объекты

 
   class Coor {  // Создаем новый класс Coor:
      var $name; // данные (свойства):
      var $addr;
      function Name(){ echo $this->name; } // метод, обращение к данным без $
   }

   $obj = new Coor;     // создаем объект класса Coor:
   $obj->name = "Alex"; // меняем значение поля
   $obj->Name();        // вызываем функцию

Наследование:

 
   class Child extends Parent {
   }

Файлы

Тип файла задаётся последним аргументом функции fopen и совпадает с параметрами этой функции C:

  • "r" - чтение; "r+" - чтение и запись; указатель в начало файла;
  • "w" - запись; "w+" - чтение и запись; в обоих случаях файл создаётся или очищается существующий;
  • "a" - дозапись в конец существующего файла; "a+" - дозапись и чтение; файл создаётся.
 
  $file = fopen("file.txt","w");
  if(file){
     fputs($file, "file id = $file\n");
     fclose($file);
  }
  else
     echo("Ошибка открытия файла");

Чтение полей xml-файла

 
<clients> 
<client> <name>John </name> <account>222</account> </client> 
<client> <name>Smith</name> <account>123</account> </client> 
</clients> 

осуществляется таким образом:

 
   $clients = simplexml_load_file('clients.xml'); 
   foreach ($clients->client as $client)
      print "$client->name has account number $client->account <br>"; 

Чтение csv-файла в массив:

 
   $file =  fopen ("rps.csv","r");      
   if($file){                            // читаем файл построчно, разбивая на поля
      while ($data = fgetcsv($file,1024,","))
         if(count($data))
            $table[] = $data;
      fclose ($file);
   }
   
   foreach ($table as $ln)                // выводим поля файла
      echo "$ln[0] $ln[1] $ln[2]\n";
      
   $table[] = Array("aaa", "bbb", 8 );    // добавляем к таблице строку
   $file = fopen('rps.csv', 'w');
   if($file){
      foreach($table as $ln)              // записываем всю строку
         fputcsv($file, $ln); 
      fclose($file);
   }

Некоторые функции

  • чтение:
    • string fgets( int file, int len); - прочитать строку длинной не более len-1 символов до конца строки или файла. При достижении конца файла возвращает пустую строку.
    • string fread( int file, int len ) - прочитать строку длинной len символов
    • string fgetss(int file, int len [, string allowable_tags]); - чтения строки с удалением из неё тегов HTML. В строке allowable_tags перечень тегов через запятую, которые не надо отбрасывать
    • array fgetcsv ( int file, int length, char delim) - чтения файлов с расширением *.csv
    • fpassthru($file); - распечатать содержимое файла
    • readfile ("file.txt"); - тоже, но передаётся строка с его именем
  • запись:
    • int fputs ( int file, string str [, int length ]) - записать строку

Ошибки

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

 
// Преднамеренная ошибка при работе с файлами
$my_file = @file ('non_existent_file') or die ("Failed opening file:'$php_errormsg'");

$value = @$cache[$key];  // Если ключа $key нет, сообщение об ошибке не будет отображено

Cookies

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

   // Устанавливаем Cookie на один час после установки:
   if( SetCookie("My_Cookie","Value",time()+3600) )
      echo "<h3>Cookies успешно установлены!</h3>";
   echo @$_COOKIE['My_Cookie']; // При следующем запросе скрипта выводит 'Value' (см. управление ошибками)

Пример, как построить счетчик числа загрузок страницы с помощью Cookies:

   $cnt = isset($_COOKIE['Visits'])? $_COOKIE['Visits']+1 : 0; // Проверяем, есть ли уже Cookie 'Visits',
   setcookie("Visits",$cnt,0x6FFFFFFF);      // Устанавливаем Cookie со временем "жизни" до 18/07/29,
   echo "Страница посещалась".$cnt."раз";    // Выводим число посещений этой страницы:

Можно установить массив Cookies:

   // Устанавливаем массив Cookies:
   setcookie("cookie[1]", "Первый");   
   setcookie("cookie[2]", "Второй");

   // После перезагрузки страницы мы отобразим массив Cookies 'cookie':
   if (isset($_COOKIE['cookie'])) {
       foreach ($_COOKIE['cookie'] as $name => $value)
          echo "$name : $value <br>";
   }

Библиотеки

Конструкция require имя_файла; позволяет собирать сценарии PHP из нескольких отдельных файлов, которые могут быть как html-страницами, так и php-скриптами. При запуске программы интерпретатор просто заменит инструкцию на содержимое файла имя_файлаперед запуском программы (в отличие от include).

Конструкция include имя_файла; позволяет включать файлы в код PHP скрипта во время выполнения сценария. Дойдя до include, PHP прекращает транслировать сценарий и переключается на указанный в include файл. При этом быстродействие сценария снижается (при большом количестве include файлов). С require таких проблем нет, поскольку файлы с помощью require включаются до выполнения сценария, то есть на момент трансляции файл уже включен в сценарий.

Целесообразнее использовать конструкцию require там, где не требуется динамическое включение файлов в сценарий, а конструкцию include использовать только с целью динамического включения файлов в код PHP скрипта.

Используя конструкции однократного включения require_once и include_once, можно быть уверенным, что один файл не будет включен дважды. Работают конструкции однократного включения require_once и include_once так же, как и require и include соответственно. Разница в их работе лишь в том, что перед включением файла интерпрететор проверяет, включен ли указанный файл ранее или нет. Если да, то файл не будет включен вновь.

Примеры

Ссылки

  • php.su - справочник и учебник по PHP
  • wipmania.com - определение страны, провайдера по ip адресу, иконки всех флагов

См.также