четверг, 3 декабря 2009 г.

Поиграем с PHP

Автор: Николай Рудченко

http://www.codeguru.com.ua

20 февраля 2006 года

Дело было вечером, а может и нет - не припомню :) Под звуки Dj Quicksilver'a я, продолжая свое изучение PHP, дошел до раздела "Работа со строками". Благо там все было написано понятным языком, поэтому после прочтения раздела возникло желание "закрепить" полученные знания на практике.

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

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

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

Надеюсь, веб-сервер (какой - выбирать вам; лично я использую Apache) у вас настроен. Если нет, то в "МК" было несколько статей по настройке различных веб-серверов. Будет желание - найдете непременно.

Начнем с написания скрипта, а назовем наш его pole_chudes.php:

<?php

// Количество возможных попыток (пусть будет пол-алфавита);
$let_num = 16;    

// наш массив-"алфавит";
$alphabet = array(
  "А","Б","В","Г","Д","Е","Ж","З","И","Й","К","Л","М","Н","О","П",
  "Р","С","Т","У","Ф","Х","Ц","Ч","Ш","Щ","Ъ","Ы","Ь","Э","Ю","Я");

// Массив возможных слов,
$words = array("МАГИЯ","ЛАМПА","КАРТА","МОНИТОР","МУЗЫКА");
      
// из которых случайным образом будет выбрано слово,
// которое игрок будет угадывать;

// Выбираем слово наугад;
if (!isset($word_number)){
  $word_number = rand(1,count($words)) - 1;
                         }

// $word - короткий псевдоним для $words[$word_number];
$word = $words[$word_number];

echo"<H1>"; /* Начинаем выводить загаданное слово
(вместо еще "неугаданных" букв - у нас будет знак подчеркивания "_"),
 заодно проверяем, может оно уже отгадано; */

// Предположим, что это так (т.е. угадано) установкой флага $finished.
$finished = 1; 

// Перебираем все буквы слова;
for ($i=0; $i < strlen($word); $i++) {

/* Если $i-ю букву слова игрок уже "назвал" и она есть в загаданном слове,*/
  if (ereg($word[$i], $letters)){  
/* то выводим, ее на экран. (Тут $letters - множество "названных" букв);*/
    echo $word[$i];                
                                }
  else {
// В противном случае выводим знак подчеркивания "_".
    echo "_";                    
// Заодно отмечаем, что слово еще не отгадано.
    $finished = 0;                
       }
}
echo"</H1>";

// Если слово угадано, то появляется сообщение:
if ($finished){                    
  echo "<BR><BR><I>ПОЗДРАВЛЯЕМ! ВЫ ВЫИГРАЛИ!</I><BR><BR>";
  echo  "<A HREF=$PHP_SELF><IMG SRC=\"./play_again.jpg\"></A>";  

/* Предлагаем игроку сыграть еще раз,
  нажав на кнопку с надписью "Сыграем еще?" 
("кнопка" есть не что иное как картинка "play_again.jpg" в
 одном каталоге с нашем файлом pole_chudes.php). */ 
               }

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

letters=$letters$var - к множеству "названных" букв $letters добавим текущую букву $var. Зачем это нужно? Для того, что если игрок нажмет на нее, она ведь тоже станет "названной".

Введем еще такие переменные:

word_number=$word_number - номер загаданного слова;

last=$var - последняя "названная" буква.

else {
      $links .= "<A HREF=
\"$PHP_SELF?letters=$letters$var&word_number=$word_number&last=$var\">$var</A> ";
             }
  }

На заключительном этапе необходимо предусмотреть такие варианты:

  • играющий превысил установленное количество попыток (переменная $let_num);
  • буква,"названная" играющим, правильная или нет (других вариантов лично я не вижу - может вы знаете ?).

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

В нашем случае пусть это будут картинки с соответствующим содержанием.





  /* Если игрок превысил лимит попыток (т.е проиграл ),то так ему об этом и скажем:*/
  if ($wrong == $let_num) { 

    echo "<BR>НА ЭТОТ РАЗ ВАМ НЕ ПОВЕЗЛО!<BR><BR>";
    echo "СЛОВО, КОТОРОЕ ВЫ ТАК И НЕ УГАДАЛИ: \"$word\"<BR><BR>";
        echo "<A HREF=$PHP_SELF><IMG SRC=\"./play_again.jpg\"></A>  "; 
// Опять предложим сыграть,для реванша, так сказать.

      }
   else {
      if (isset($last)) {

/* Если переменная $last уже была инициализирована,то  необходимо проверить,
 является ли она правильной. Т.е если переменная $lastприсутствует в строке
$word - нашем загаданном слове.*/
   
         // Если да (т.е. буква названа правильно),
         // то появиться картинка с надписью "Угадал!"";
         if (ereg($last,$word)) {
            echo "<BR><IMG SRC=\"./all_right.jpg\"><BR>"; 
            }
         // если нет, то так и скажем "А вот и не угадал".
         else {
              echo "<BR><IMG SRC=\"./try_again.jpg\"><BR>";  
            }
         }
      echo "<BR><BR>";
      echo "ОСТАЛОСЬ ПОПЫТОК = ".($let_num-$wrong)."<BR>"; // без комментариев;
      echo "<BR>ПОЖАЛУЙСТА ВЫБЕРИТЕ БУКВУ:<BR><BR>";
      echo $links;
      }
   }
?>

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

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

Особую благодарность хочу выразить Дмитрию Кравченко за помощь в подготовке данной статьи и Roxton'у за его супер-редактор TEA.

Скачать исходник [ZIP, 2.1Kb]

5 мифов Web программирования

Автор: Kotov

Блог PHP разработчика

2 января 2007 года

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

Миф №1. C++/Pascal рулят миром.

Многие думают что, только такие гиганты программирования как Страуструп могут создать идеальный язык. Нет, на самом деле действительно на C можно написать все, что только можно реализовать в виде логической цепочки действий, но(!): обращу ваше внимание на слово "написать". Т.е. написать то можно, но вот сколько это потребует усилий, какова будет цена выбора в пользу "идеального" языка. Возьмем, например PHP. Все знают (ну теперь точно все), что интерпретатор PHP написать на C. Что из этого следует? А то, что для того что бы писать скрипты для web на C так же легко и быстро, нужно будет написать аналог PHP. Все дело в задаче и "себестоимости" ее выполнения.

Миф №2. Web программист никогда не напишет "ничего серьезного".

Под "серьезным" обычно понимается масштабный проект, который отнимает кучу времени нервов, но приносит таки "достойное" вознаграждение. ОК, вот аналогия из жизни. Капуста на рынке стоит N, в магазине эта же капуста стоит 1,25N, в супермаркете premium класса эта же капуста стоит 5N, а на базаре на рублевке эта же капуста стоит 1000N. И что, кто тут рубит капусту (пишет что-то серьезное)? Так вот, имхо, вопрос не в том, как вырастить капусту (написать программу), а как ее продать, а это уже вопрос из области маркетинга и программирование (хоть на PHP, хоть на C/Pascal) тут вообще не причем.

Миф №3. Лучше начинать учиться со "сложных" языков.

Отчасти, да. Вот только, как всегда завеса тайны, внесла коррективы трактовку этой фразы. Действительно что бы понять суть азы программирования (типы данных, ссылки, основы ООП) лучше начинать изучать тот язык где эти самые азы реализованы лучше всего, но(!): Обычно фраза "Лучше начинать учиться со "сложных" языков" употребляется в том контексте, что допустим человек выучивший PHP не сможет перейти допустим на C. Повторюсь PHP написан на C и унаследовал очень много от прорадителя. Значит PHP похож на C, ровно столько же сколько C похож на PHP. Почему кто-то не сможет перейти от простого к сложному, а от сложного к простому этот же самый человек сможет. Т.е. не изучая PHP вы способны изучить C, а вот освоив PHP вы сразу же, по мановению волшебной палочки, теряете свойство "могу изучить C". Бред!

Миф №4. Пиши с нуля.

Этот миф часто возникает сам по себе в головах начинах кодеров. "Ах, сколько кода, как долго с ним разбираться": "лучше я напишу свой аналог, в котором будет присутствовать только "то, что мне нужно"". Почему это миф? Во-первых, если сложно понять, чужой код, то это еще не значит что он плохой. Во-вторых, составляем список "того что нужно", сравниваем с тем, что есть и забиваем на "пиши с нуля". Лучше писать надстройки для, например, управлениями обмена ссылками между 10 (100,1000 нужное подчеркнуть) форумов, модули ко всяким CMS наконец. Другое дело, если кодить что-то уникальное по своей природе, но в 99,99% случаях фраза "пиши с нуля" употребляется из-за нежелания разбираться в чужом коде и учиться в целом. Психологический вопрос, имхо. Конечно, можно кодить с нуля для "закрепления пройденного материала", но опять же это укладывается в те самые 0,001%.

Миф №5. Все уже написано.

Вот только не надо опускать руки! На самом деле написано настолько мало, что аж [censored]! Другое дело, если в процессе обучения (практики) кодинга, возникает ситуация когда не находится задачи к которой стоит "приложить руки". И вот тут в игру вступают "срули". У них все написано, все сделано, все места заняты: пора пойти и застрелится. Что тут можно сказать. Люди, это не программирование придумает задачи для жизни, а жизнь дает пишу (кусочек хлебушка и чашку и икорочкой) программисту. Не там ищите идеи. Действительно, накодить что-нить очень тяжело, а вот например накодить парсер, новостного сайта сложнее, еще сложнее усовершенствовать его и сделать настраиваемые уведомленения по e-mail, icq и sms. Еще сложнее написать систему отслеживания копий текста с сайта (мало ли кто-то "чисто случайно" забыл поставить ссылку на вас). Да много чего можно сделать.

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

Создание EXE приложений на PHP

Автор: S1B aka Furius Angel (Security Bunker Team)

www.secbun.info

INTRO


Все мы знаем что PHP предназначен для быстрого создания динамических Web страниц. Во всяком случае именно это написано на официальном сайте разработчиков PHP. Однако почему бы не попробовать найти PHP "немного" иное применение, например, попробовать создать полноценное приложение для Windows? Заинтересовал? Тогда понеслась!

Чёрный квадрат


Приложения делятся на консольные и оконные. Начнём с создания первых, так как это проще. Итак, для начала нужно определиться с тем, что мы будем писать... я предлагаю написать простой MD5 & Base64 Encoder - вещь в хозяйстве нужная и полезная, тем более здесь всё достаточно просто. Для запуска PHP скрипта из командной строки и передачи ему нужных параметров используется следующая конструкция:

php.exe [опции] [-f] <наш скрипт> [параметры]

Что касается содержания самого скрипта, то количество переданных параметров хранится в переменной $argc, а сами параметры хранятся в массиве $argv. На этом краткий инструктаж по консольным приложениям закончен и пришла пора приступить к активным действиям.

Чтобы не утруждать Вас написанием скрипта, я решил написать его за Вас. Вот что у меня получилось:

<?php
if($argc!=3) { echo "
+--------------------------------------+
|  Create MD5 hash: enc md5 string     |
|  Create Base64 hash: enc b64 string  |
+--------------------------------------+\n";
} else {
echo "\n";
 if($argv[1]=='md5') { // MD5 encode
  echo md5($argv[2])."\n\n"; die();
  }
  if($argv[1]=='b64') { // Base64 encode
  echo base64_encode($argv[2])."\n\n"; die();
  } else { echo "Unknown command. Type \"enc\" for help.\n\n"; }
}
?>





Скрипт написан и теперь самое интересное - компиляция в EXE приложение. Для компиляции консольных приложений я использую Roadsend Compiler Studio. Его можно
скачать на сайте www.roadsend.com после
бесплатной регистрации. Скачали? Теперь открываем Roadsend IDE, создаём новый
проект (Project -> New), прописываем необходимые параметры (наш скрипт
рекомендую кинуть именно в директорию проекта), жмём "OK" и наконец даём
заветное Project -> Build. Теперь направляемся в папку с проектом и если Вы
всё правильно сделали - в ней Вы найдёте готовый EXE. Это всё? Да. Всё просто,
если знать некоторые нюансы. Единственное что я рекомендовал бы - иногда полезно
пошаманить с подключаемыми библиотеками, а так же можно упаковать наш EXE UPX`м,
хотя эту тему я затрону чуть ниже. Теперь перейдём к оконным приложениям...

Окошки


Как Вы наверное уже догадались - при создании оконных приложений штатными
средствами PHP уже не обойтись, поэтому для начала нужно выбрать инструмент для
разработки нашего окошка. Среди всех инструментов больше всего выделяются два -
это достаточно раскрученый PHP-GTK (www.gtk.php.net) и менее раскрученный, но не
менее функциональный WinBlider (www.winbinder.org). Здесь как раз тот
случай, когда более раскрученный и известный оказывается не так уж и хорош (это
моё имхо), поэтому для разработки нашей первой форточки на PHP мы будем
использовать WinBlinder. Для начала его нужно скачать. Готово? Окей, двигаемся
дальше...

Винблиндер имеет свой собственный формат данных - phpw, который Вы можете сразу смело привязывать к вашему любимому редактору кода. По умолчанию при запуске phpw файла открывается содержащийся в нём PHP скрипт и прогоняется через интерпретатор с уже подключеными библиотеками блиндера. Как Вы наверное поняли - учится программировать на этой балалайке Вам придётся самим, однако в это нет ничего сложного, особенно человеку хоть немного знакомому с ООП в PHP. Однако даже незнакомый тоже сможет на нём кодить, так как по сути блиндер (в отличии от PHP-GTK) поддерживает и процедурное программирование. Кроме того WinBlinder весьма неплохо документирован, а инсталл архив уже содержит в себе несколько весьма любопытных примеров (особое внимание прошу обратить на редактор форм). У блиндера есть ещё куча фишек, функций и интересностей, но рамки данной статьи не позволяют мне на них останавливаться. Теперь пожалуй самое подходящее время вспомнить о нашем кодере. Чтобы не перегружать всё кодом я решил написать лишь MD5 Encoder:

<?

// Подключаем основную библиотеку
include "include/winbinder.php";

// Даём метки окнам редактирования
define('IDC_EDITBOX1002', 1002);
define('IDC_EDITBOX1003', 1003);

// Рисуем окошко
$winmain = wb_create_window(null,
  AppWindow,
  'MD5 Hash Generator by S1B [SBT]',
  WBC_CENTER, WBC_CENTER, 315, 134,
  0x00000000, 0);

// Шпигуем окошко кнопками

# Рисуем рамочку
wb_create_control($winmain, Frame, '', 10, 10, 290, 85, 0, 0x00000000, 0, 0);
# Рисуем надписи (лейблы)
wb_create_control($winmain, Label, 'Текст:', 23, 35, 45, 15, 0, 0x00000000, 0, 0);
wb_create_control($winmain, Label, 'Hash:', 23, 65, 45, 15, 0, 0x00000000, 0, 0);
# Рисуем окошки редактирования (нижнее будет неактивным), и загоняем их данные в переменные
$text=wb_create_control($winmain, EditBox, '', 78, 30, 210, 20, IDC_EDITBOX1002, 0x00000000, 0, 0);
$hash=wb_create_control($winmain, EditBox, '', 78, 60, 210, 20, IDC_EDITBOX1003, 0x00000040, 0, 0);

// Две необходимые надписи =)
wb_set_handler($winmain, "process_main");
wb_main_loop();

function process_main($window,$id) {
  # Объявляем данные окошек редактирования глобальными
 global $text,$hash;
 switch($id) {
  case IDC_EDITBOX1002:
    wb_set_text($hash,md5(wb_get_text($text)));
  break;
  case IDCLOSE:
   wb_destroy_window($window);
  break;
 }
}

?>

Код достаточно прост и думаю посидев с документацией 1-2 часа Вы начнёте
разбираться в нём так же, как и я. Ну а теперь кульминация - собираем
форточку... Для этого предлагаю создать отдельную директорию и перенести наш
скрипт туда. Так же нужно перенести туда папку include из phpcode директории
винблиндера. Готово? Теперь компилируем! Эээ... стоп не нужно хвататься за
Roadsend IDE. Как? А вот так! Он не поддерживает блиндер, а поддерживает только
GTK, причём судя по туманным ответам разработчиков Roadsend на их форуме -
поддержку блиндера можно ещё долго ждать. Однако вытрем сопли, и будем искать
другие пути, и имя этим путям Bamcompile (www.bambalam.se/bamcompile/).
Однако по каким-то причинам версия 1.21 не всегда верно работает и иногда
компилирует всё в неработающее приложение, однако версия 1.1 такими глюками не
страдает, поэтому рекомендую использовать её. Теперь щедро выделяем для нашего
компилятора отдельную папку, заходим в командную строку и гордо командуем:

bambalam -w -c C:\PHP_Projects\MD5_Hash_Generator\ md5.phpw md5.exe





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




Волшебный ларец


Все вышесказанное конечно весьма интересне и познавательно, однако бывают моменты когда нужных инструментов под рукой нет... Что делать тогда? Специально для такого случая есть один весьма любопытный приём получения EXE через шаманство в опциях SFX архива WinRAR. В качестве примера я буду использовать наш первый скрипт для консоли. Для начала помещаем наш скрипт в отдельную папку, туда же копируем php.exe и php*ts.dll. Далее создаём в этой же папке run.bat следующего содержания:

@echo off
php.exe -q console.php %1 %2

Теперь нам необходимо это добро упаковать, для этого выделяем все файлы, жмём правой кнопкой и выбираем "Add to archive...".




В появившемся окне выбираем формат архива RAR, выставляем максимальное сжатие и ставим галочку "Create SFX archive".




После этого переходим во складку "Advanced -> SFX Options", там выставляем переключатель на "Create in curent folder" и в "Run after extraction" прописываем "run.bat", а так же во вкладке "Modes" выставляем галочку "Unpack to temporary folder", а так же выставляем переключатели "Hide all" и "Overwrite all files".




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

OUTRO


Итак, сегодня я показал Вам, как легко и просто можно раздвинуть границы использования PHP. Конечно кто-то всё это назовёт бредом, скажет мол размер у приложений большой, и память у них течет, и муторно всё это. Пусть говорят, однако никто не призывает Вас писать все оконные приложения на PHP, а данная статья лишь неплохое подспорье для пхп кодеров и всех интересующихся. На сим я закончу. Удачи.

Создание EXE приложений на PHP

Автор: S1B aka Furius Angel (Security Bunker Team)

www.secbun.info

INTRO


Все мы знаем что PHP предназначен для быстрого создания динамических Web страниц. Во всяком случае именно это написано на официальном сайте разработчиков PHP. Однако почему бы не попробовать найти PHP "немного" иное применение, например, попробовать создать полноценное приложение для Windows? Заинтересовал? Тогда понеслась!

Чёрный квадрат


Приложения делятся на консольные и оконные. Начнём с создания первых, так как это проще. Итак, для начала нужно определиться с тем, что мы будем писать... я предлагаю написать простой MD5 & Base64 Encoder - вещь в хозяйстве нужная и полезная, тем более здесь всё достаточно просто. Для запуска PHP скрипта из командной строки и передачи ему нужных параметров используется следующая конструкция:

php.exe [опции] [-f] <наш скрипт> [параметры]

Что касается содержания самого скрипта, то количество переданных параметров хранится в переменной $argc, а сами параметры хранятся в массиве $argv. На этом краткий инструктаж по консольным приложениям закончен и пришла пора приступить к активным действиям.

Чтобы не утруждать Вас написанием скрипта, я решил написать его за Вас. Вот что у меня получилось:

<?php
if($argc!=3) { echo "
+--------------------------------------+
|  Create MD5 hash: enc md5 string     |
|  Create Base64 hash: enc b64 string  |
+--------------------------------------+\n";
} else {
echo "\n";
 if($argv[1]=='md5') { // MD5 encode
  echo md5($argv[2])."\n\n"; die();
  }
  if($argv[1]=='b64') { // Base64 encode
  echo base64_encode($argv[2])."\n\n"; die();
  } else { echo "Unknown command. Type \"enc\" for help.\n\n"; }
}
?>





Скрипт написан и теперь самое интересное - компиляция в EXE приложение. Для компиляции консольных приложений я использую Roadsend Compiler Studio. Его можно
скачать на сайте www.roadsend.com после
бесплатной регистрации. Скачали? Теперь открываем Roadsend IDE, создаём новый
проект (Project -> New), прописываем необходимые параметры (наш скрипт
рекомендую кинуть именно в директорию проекта), жмём "OK" и наконец даём
заветное Project -> Build. Теперь направляемся в папку с проектом и если Вы
всё правильно сделали - в ней Вы найдёте готовый EXE. Это всё? Да. Всё просто,
если знать некоторые нюансы. Единственное что я рекомендовал бы - иногда полезно
пошаманить с подключаемыми библиотеками, а так же можно упаковать наш EXE UPX`м,
хотя эту тему я затрону чуть ниже. Теперь перейдём к оконным приложениям...

Окошки


Как Вы наверное уже догадались - при создании оконных приложений штатными
средствами PHP уже не обойтись, поэтому для начала нужно выбрать инструмент для
разработки нашего окошка. Среди всех инструментов больше всего выделяются два -
это достаточно раскрученый PHP-GTK (www.gtk.php.net) и менее раскрученный, но не
менее функциональный WinBlider (www.winbinder.org). Здесь как раз тот
случай, когда более раскрученный и известный оказывается не так уж и хорош (это
моё имхо), поэтому для разработки нашей первой форточки на PHP мы будем
использовать WinBlinder. Для начала его нужно скачать. Готово? Окей, двигаемся
дальше...

Винблиндер имеет свой собственный формат данных - phpw, который Вы можете сразу смело привязывать к вашему любимому редактору кода. По умолчанию при запуске phpw файла открывается содержащийся в нём PHP скрипт и прогоняется через интерпретатор с уже подключеными библиотеками блиндера. Как Вы наверное поняли - учится программировать на этой балалайке Вам придётся самим, однако в это нет ничего сложного, особенно человеку хоть немного знакомому с ООП в PHP. Однако даже незнакомый тоже сможет на нём кодить, так как по сути блиндер (в отличии от PHP-GTK) поддерживает и процедурное программирование. Кроме того WinBlinder весьма неплохо документирован, а инсталл архив уже содержит в себе несколько весьма любопытных примеров (особое внимание прошу обратить на редактор форм). У блиндера есть ещё куча фишек, функций и интересностей, но рамки данной статьи не позволяют мне на них останавливаться. Теперь пожалуй самое подходящее время вспомнить о нашем кодере. Чтобы не перегружать всё кодом я решил написать лишь MD5 Encoder:

<?

// Подключаем основную библиотеку
include "include/winbinder.php";

// Даём метки окнам редактирования
define('IDC_EDITBOX1002', 1002);
define('IDC_EDITBOX1003', 1003);

// Рисуем окошко
$winmain = wb_create_window(null,
  AppWindow,
  'MD5 Hash Generator by S1B [SBT]',
  WBC_CENTER, WBC_CENTER, 315, 134,
  0x00000000, 0);

// Шпигуем окошко кнопками

# Рисуем рамочку
wb_create_control($winmain, Frame, '', 10, 10, 290, 85, 0, 0x00000000, 0, 0);
# Рисуем надписи (лейблы)
wb_create_control($winmain, Label, 'Текст:', 23, 35, 45, 15, 0, 0x00000000, 0, 0);
wb_create_control($winmain, Label, 'Hash:', 23, 65, 45, 15, 0, 0x00000000, 0, 0);
# Рисуем окошки редактирования (нижнее будет неактивным), и загоняем их данные в переменные
$text=wb_create_control($winmain, EditBox, '', 78, 30, 210, 20, IDC_EDITBOX1002, 0x00000000, 0, 0);
$hash=wb_create_control($winmain, EditBox, '', 78, 60, 210, 20, IDC_EDITBOX1003, 0x00000040, 0, 0);

// Две необходимые надписи =)
wb_set_handler($winmain, "process_main");
wb_main_loop();

function process_main($window,$id) {
  # Объявляем данные окошек редактирования глобальными
 global $text,$hash;
 switch($id) {
  case IDC_EDITBOX1002:
    wb_set_text($hash,md5(wb_get_text($text)));
  break;
  case IDCLOSE:
   wb_destroy_window($window);
  break;
 }
}

?>

Код достаточно прост и думаю посидев с документацией 1-2 часа Вы начнёте
разбираться в нём так же, как и я. Ну а теперь кульминация - собираем
форточку... Для этого предлагаю создать отдельную директорию и перенести наш
скрипт туда. Так же нужно перенести туда папку include из phpcode директории
винблиндера. Готово? Теперь компилируем! Эээ... стоп не нужно хвататься за
Roadsend IDE. Как? А вот так! Он не поддерживает блиндер, а поддерживает только
GTK, причём судя по туманным ответам разработчиков Roadsend на их форуме -
поддержку блиндера можно ещё долго ждать. Однако вытрем сопли, и будем искать
другие пути, и имя этим путям Bamcompile (www.bambalam.se/bamcompile/).
Однако по каким-то причинам версия 1.21 не всегда верно работает и иногда
компилирует всё в неработающее приложение, однако версия 1.1 такими глюками не
страдает, поэтому рекомендую использовать её. Теперь щедро выделяем для нашего
компилятора отдельную папку, заходим в командную строку и гордо командуем:

bambalam -w -c C:\PHP_Projects\MD5_Hash_Generator\ md5.phpw md5.exe





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




Волшебный ларец


Все вышесказанное конечно весьма интересне и познавательно, однако бывают моменты когда нужных инструментов под рукой нет... Что делать тогда? Специально для такого случая есть один весьма любопытный приём получения EXE через шаманство в опциях SFX архива WinRAR. В качестве примера я буду использовать наш первый скрипт для консоли. Для начала помещаем наш скрипт в отдельную папку, туда же копируем php.exe и php*ts.dll. Далее создаём в этой же папке run.bat следующего содержания:

@echo off
php.exe -q console.php %1 %2

Теперь нам необходимо это добро упаковать, для этого выделяем все файлы, жмём правой кнопкой и выбираем "Add to archive...".




В появившемся окне выбираем формат архива RAR, выставляем максимальное сжатие и ставим галочку "Create SFX archive".




После этого переходим во складку "Advanced -> SFX Options", там выставляем переключатель на "Create in curent folder" и в "Run after extraction" прописываем "run.bat", а так же во вкладке "Modes" выставляем галочку "Unpack to temporary folder", а так же выставляем переключатели "Hide all" и "Overwrite all files".




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

OUTRO


Итак, сегодня я показал Вам, как легко и просто можно раздвинуть границы использования PHP. Конечно кто-то всё это назовёт бредом, скажет мол размер у приложений большой, и память у них течет, и муторно всё это. Пусть говорят, однако никто не призывает Вас писать все оконные приложения на PHP, а данная статья лишь неплохое подспорье для пхп кодеров и всех интересующихся. На сим я закончу. Удачи.




Комментарии пользователей (всего 8)



diskat / 03 августа 2008, 19:10:26

Эх.. после 200 инклюдов и 15 минут компиляции узнать что sha1() еще не поддерживается.. можно было и предупредить..



diskat / 03 августа 2008, 19:09:06

Эх.. после 200 инклюдов и 15 минут компиляции узнать что sha1() еще не поддерживается.. можно было и предупредить..



diskat / 03 августа 2008, 19:08:53

Эх.. после 200 инклюдов и 15 минут компиляции узнать что sha1() еще не поддерживается.. можно было и предупредить..



Dir / 13 февраля 2008, 00:57:23

скачал WinBlider, установил...но при запуске php-win.exe выдает ошибку -

"Точка входа в процедуру _zval_copy_ctor_func не найдена в библиотеке DLL php5ts.dll"

"PHP Startup: Unable to load dynamic library 'C:PHPextphp_mssql.dll' - Не найдена указанная процедура"



и потом покругу теже ошибки только указаны другие процедуры - zend_std_get_constructor - php5ts.dll

php_mysqli.dll

_zval_copy_ctor_func - php5ts.dll

php_gettext.dll

php_gmp.dll

php_filepro.dll

php_mbstring.dll

_safe_malloc - php5ts.dll

php_pdo.dll

php_sqlite.dll

php_dbase.dll

php_dbx.dll



Не подскажете в чем проблема и как исправить.

У меня стоит php 5.2.4 под апатчем, сам он прекрасно работает

спасибо



ko1yan / 29 декабря 2007, 18:15:00

При нажатии на Project -> Build выдаёт ошибку

binary is not set



в чём проблема?



oskin / 16 ноября 2007, 14:23:03

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

На подобие вышеприведенного примера.



В комплекте Winbinder идет formeditor тоже написанный на php.



Попробовал поработать с пол часа, ужаснулся от файла - подкачки, который раздулся до 1,7 Гб. Так же пытался написать календарь - ежедневник, то же черезмерное использование ресурсов.

Буду смотреть на PHP-GTK



S1B / 20 апреля 2007, 22:02:18

Спасибо за комент. Теперь пользователи точно разберутся ;)



dimon7k / 10 апреля 2007, 20:49:17

Вообще для создания работоспособных экзешников биндеровских десктопных приложений с помощью bamcompile 1.21, как я понял, в проект надо подключать библиотеку php_winbinder.dll. Тогда все ОК (по крайней мере скрипт, приведенный в статье, прекрасно пашет).

И, как пишется в readme bamcompile-архива, фишкой этого компиллятора, начиная с версии 1.2, является возможность подключения к проекту дополнительных библиотек, что было недоступно ранее. Так, можно написать биндеровский (рнр-шный) скрипт, прекрасно работающий с библиотекой gd_2, но после создания соответствующего экзешника с помощью bamcompile 1.1, в приложении будут недоступны графические функции; в версии же bamcompile 1.21 указанную gd_2-библиотеку можно подключить к проекту, и полученный экзешник уже будет выполнять соответствующие графические функции.

А вообще смотрите примеры папки examples bamcompile-архива - можно найти что-то полезное (в плане того, ка как задавать создание єкзешника).




PHP и Upload (Загрузка файлов на сервер)

 

 

PHP и Upload (Загрузка файлов на сервер)

Multipart-формы

Загрузка фаилов на сервер осуществляется пользователями сети интернет довольно часто, а именно:

  • Веб-итерфейсы почтовых сервисов, которые позволяют добавалять к письму приложение (attach), а для этого нужно сначала загрузить файл на сервер, и только после этого его можно добавлять к письму;
  • Интерактивные фотогалереи и фотоальбомы, которые не могут существовать без механизма загрузки файлов на сервер;
  • Порталы бесплатного програмного обеспечения, которые используют для обмена файлами различных программ, и.т.д.

Загрузка файла на сервер осуществляется с помощью multipart-формы, в которой есть поле загрузки файла. В качестве параметра enctype указывается значение multipart/form-data:

<form action=upload.php method=post enctype=multipart/form-data>

<input type=file name=uploadfile>

<input type=submit value=Загрузить></form>

Вот так примерно будет выглядеть приведенная multipart-форма (вы можете попробовать с ее помощью посмотреть результат работы multipart-форм, загрузив какой-нибудь файл небольшого размера на сервер):


Multipart-формы обычно используют метод передачи POST. Как видно из предыдущего примера, данная форма имеет два поля:

  • Поле выбора файла для закачки <INPUT type=File>;
  • Поле указания имени файла, которое он должен будет иметь на сервере <INPUT type=text>.

Обработка multipart-форм

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

Конфигурационный файл PHP php.ini имеет три параметра, связанные с загрузкой файлов на сервер:

  • file_uploads=On - разрешает загрузку файлов на сервер по протоколу HTTP;
  • upoad_tmp_dir=/tmp - устанавливает каталог для временного хранения загруженных файлов;
  • upload_max_filesize=2M - устанавливает максимальный объем загружаемых файлов.

Если ваш веб-сервер работает под управлением операционной системы Linux, то нужно перезапустить сервис:

service httpd restart

Как же PHP обрабатывает multipart-формы? Получив файл, он сохраняет его во временном каталоге upload_tmp_dir, имя файла выбирается случайным образом. Затем он создает четыре переменных суперглобального массива $_FILES. Этот массив содержит информацию о загруженном файле.

Переменные, определенные для загруженных файлов, зависят от версии PHP и текущей конфигурации. Суперглобальный массив $_FILES доступен начиная с PHP 4.1.0. В случае, если конфигурационная директива register_globals установлена значением on, дополнительно будут объявлены переменные с соответствующими именами. Начиная с версии 4.2.0 значением по умолчанию для опции register_globals является off.

Содержимое массива $_FILES для нашего примера приведено ниже. Обратите внимание, что здесь предполагается использование имени uploadfile для поля выбора файла, в соответствии с приведенной выше multipart-форме. Разумеется, имя поля может быть любым.

  • $_FILES['uploadfile']['name'] - имя файла до его отправки на сервер, например, pict.gif;
  • $_FILES['uploadfile']['size'] - размер принятого файла в байтах;
  • $_FILES['uploadfile']['type'] - MIME-тип принятого файла (если браузер смог его определить), например: image/gif, image/png, image/jpeg, text/html;

  • $_FILES['uploadfile']['tmp_name'] (так мы назвали поле загрузки файла) - содержит имя файла во временном каталоге, например: /tmp/phpV3b3qY;
  • $_FILES['uploadfile']['error'] - Код ошибки, которая может возникнуть при загрузке файла. Ключ ['error'] был добавлен в PHP 4.2.0. С соответствующими кодами ошибок вы можете ознакомиться здесь

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

Если кнопка "Submit" нажата, то файл уже будет загружен на сервер и его имя будут в переменной $_FILES['uploadfile']['name']. В этом случае скрипт должен сразу скопировать файл с именем $_FILES['uploadfile']['tmp_name'] в какой-нибудь каталог (необходимы права на запись в этот каталог).

Копирование файла производится функцией copy():

Используйте только функцию копирования copy(), а не перемещения, поскольку:

  • Временный файл будет удален фвтоматически;
  • Если временный каталог находится на другом носителе, будет выведено сообщение об ошибке.

Предположим, нам нужно загрузить файл в каталог uploads, который находится в корневом каталоге веб-сервера (в каталоге DocumentRoot).

// На всякий случай создадим каталог. Если он уже создан,

// сообщение об ошибки мы не увидим, поскольку воспользуемся оператором @:


@mkdir("uploads", 0777);


// Копируем файл из /tmp в uploads

// Имя файла будет таким же, как и до отправки на сервер:


copy($_FILES['uploadfile']['tmp_name'],"uploads/".basename($_FILES['uploadfile']['name']));

В Linux все намного сложнее - нам нужно учитывать права доступа к каталогу uploads. Скорее всего в таком случае, функция mkdir() не сработает, так как у нас нет прав на запись в каталог DocumentRoot (обычно это /var/www/html или /home/httpd/html). Зарегистрируйтесь в системе как пользователь root, создайте каталог uploads и измените его владельца и права доступа следующим образом:

// Создаем каталог uploads


mkdir uploads


// Устанавливаем имя владельца apache и его группу - тоже apache:


chown apache:apache uploads


// Разрешение записи всем (777) + установка закрепляющего бита (1):


chmod 1777 uploads

Размер файла можно ограничить, при желании можно отредактировать файл .htaccess и ограничить доступ к каталогу uploads - указать или конкретных пользователей, которым можно обращаться к каталогу, или IP-адреса.

Вот теперь можно загружать файлы на сервер.

Пишем PHP скрипт загрузки файлов на сервер

<?php



// Каталог, в который мы будем принимать файл:

$uploaddir = './files/';

$uploadfile = $uploaddir.basename($_FILES['uploadfile']['name']);



// Копируем файл из каталога для временного хранения файлов:

if (copy($_FILES['uploadfile']['tmp_name'], $uploadfile))

{

echo "<h3>Файл успешно загружен на сервер</h3>";

}

else { echo "<h3>Ошибка! Не удалось загрузить файл на сервер!</h3>"; exit; }



// Выводим информацию о загруженном файле:

echo "<h3>Информация о загруженном на сервер файле: </h3>";

echo "<p><b>Оригинальное имя загруженного файла: ".$_FILES['uploadfile']['name']."</b></p>";

echo "<p><b>Mime-тип загруженного файла: ".$_FILES['uploadfile']['type']."</b></p>";

echo "<p><b>Размер загруженного файла в байтах: ".$_FILES['uploadfile']['size']."</b></p>";

echo "<p><b>Временное имя файла: ".$_FILES['uploadfile']['tmp_name']."</b></p>";



?>

Загрузка на сервер нескольких файлов

Загрузку нескольких файлов можно реализовать используя, например, различные значения name для тега input.

Также предусмотрена возможность автоматического получения организованной в массив информации о нескольких одновременно загружаемых файлах. Для реализации такой возможности используйте тот же синтаксис отправки массива из HTML-формы, что и для множественных полей select и checkbox:

<form action="upload.php" method="post" enctype="multipart/form-data">

Send these files:<br>

<input name="userfile[]" type="file"><br>

<input name="userfile[]" type="file"><br>

<input type="submit" value="Отправить файлы ">

</form>

В случае, если такая форма была отправлена, массивы $_FILES['userfile'], $_FILES['userfile']['name'], и $_FILES['userfile']['size'] будут инициализированы (точно так же, как и $HTTP_POST_FILES для PHP 4.1.0 и более ранних версий). Если конфигурационная директива register_globals установлена значением on, также будут инициализированы сопутствующие глобальные переменные. Каждая из таких переменных будет представлять собой численно индексированный массив соответствующих значений для принятых файлов.

Предположим, что были загружены файлы /home/test/some.html и /home/test/file.bin. В таком случае переменная $_FILES['userfile']['name'][0] будет иметь значение some.html, а переменная $_FILES['userfile']['name'][1] - значение file.bin. Аналогично, переменная $_FILES['userfile']['size'][0] будет содержать размер файла some.html и так далее.

Переменные $_FILES['userfile']['name'][0], $_FILES['userfile']['tmp_name'][0], $_FILES['userfile']['size'][0] и $_FILES['userfile']['type'][0] также будут инициализированы.

Заключение:

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

 

Классы и объекты в PHP

 

 

Классы и объекты в PHP

Класс - это базовое понятие в объектно-ориентированном программировании (ООП). Классы образуют синтаксическую базу ООП. Их можно рассматривать как своего рода "контейнеры" для логически связанных данных и функций (обычно называемых методами — см. ниже). Если сказать проще, то класс - это своеобразный тип данных.

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

Если класс можно рассматривать как тип данных, то объект — как переменную (по аналогии). Скрипт может одновременно работать с несколькими объектами одного класса, как с несколькими переменными.

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

Описание классов в PHP начинаются служебным словом class:

class Имя_класса {

// описание членов класса - свойств и методов для их обработки

}

Для объявления объекта необходимо использовать оператор new:

Объект = new Имя_класса;

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

Подведем промежуточные итоги: объявление класса должно начинаться с ключевого слова class (подобно тому, как объявление функции начинается с ключевого слова function). Каждому объявлению свойства, содержащегося в классе, должно предшествовать ключевое слово var. Свойства могут относиться к любому типу данных, поддерживаемых в РНР, их можно рассматривать как переменные с небольшими различиями. После объявлений свойств следуют объявления методов, очень похожие на типичные объявления пользовательских функций.

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

Пример класса на PHP:

<?php

// Создаем новый класс Coor:

class Coor {

// данные (свойства):

var $name;

var $addr;



// методы:

 function Name() {

 echo "<h3>John</h3>";

 }



}



// Создаем объект класса Coor:

$object = new Coor;

?>

Доступ к класам и объектам в PHP

Мы рассмотрели, каким образом описываются классы и создаются объекты. Теперь нам необходимо получить доступ к членам класса, для этого в PHP предназначен оператор ->. Приведем пример:

<?php

// Создаем новый класс Coor:

class Coor {

// данные (свойства):

var $name;



// методы:

 function Getname() {

 echo "<h3>John</h3>";

 }



}



// Создаем объект класса Coor:

$object = new Coor;

// Получаем доступ к членам класса:

$object->name = "Alex";

echo $object->name;

// Выводит 'Alex'

// А теперь получим доступ к методу класса (фактически, к функции внутри класса):

$object->Getname();

// Выводит 'John' заглавными буквами

?>

Чтобы получить доступ к членам класса внутри класса, необходимо использовать указатель $this, которы всегда относится к текущему объекту. Модифицированный метод Getname():

function Getname() {

echo $this->name;

}

Таким же образом, можно написать метод Setname():

function Setname($name) {

$this->name = $name;

}

Теперь для изменения имени можно использовать метод Setname():

$object->Setname("Peter");

$object->Getname();

А вот и полный листинг кода:

<?php

// Создаем новый класс Coor:

class Coor {

// данные (свойства):

var $name;



// методы:

 function Getname() {

 echo $this->name;

 }



 function Setname($name) {

 $this->name = $name;

 }



}



// Создаем объект класса Coor:

$object = new Coor;

// Теперь для изменения имени используем метод Setname():

$object->Setname("Nick");

// А для доступа, как и прежде, Getname():

$object->Getname();

// Сценарий выводит 'Nick'

?>

Указатель $this можно также использовать для доступа к методам, а не только для доступа к данным:

function Setname($name) {

$this->name = $name;

$this->Getname();

}

Конструкторы

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

<?

class Webpage {

var $bgcolor;

 function Webpage($color) {

 $this->bgcolor = $color;

 }

}



// Вызвать конструктор класса Webpage

$page = new Webpage("brown");

?>

Раньше создание объекта и инициализация свойств выполнялись раздельно. Конструкторы позволяют выполнить эти действия за один этап.

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

$page = new Webpage;

Во-вторых, объект можно создать при помощи конструктора, определенного в классе, — в этом случае вы создаете объект класса Webpage и присваиваете значение его свойству bgcolor:

$page = new Webpage("brown");

Деструкторы

В РНР отсутствует непосредственная поддержка деструкторов. Тем не менее, вы можете легко имитировать работу деструктора, вызывая функцию РНР unset(). Эта функция уничтожает содержимое переменной и возвращает занимаемые ею ресурсы системе. С объектами unset() работает так же, как и с переменными. Допустим, вы работаете с объектом $Webpage. После завершения работы с этим конкретным объектом вызывается функция:

unset($Webpage);

Эта команда удаляет из памяти все содержимое $Webpage. Действуя в духе инкапсуляции, можно поместить вызов unset() в метод с именем destroy() и затем вызвать его:

$Website->destroy();

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

Инициализация объектов

Иногда возникает необходимость выполнить инициализацию объекта - присвоить его свойствам первоначальные значения. Предположим, имя класса Coor и он содержит два свойства:имя человека и город его проживания. Можно написать метод (функцию), который будет выполнять инициализацию объекта, например Init():

<?php

// Создаем новый класс Coor:

class Coor {

// данные (свойства):

var $name;

var $city;



// Инициализирующий метод:

 function Init($name) {

 $this->name = $name;

 $this->city = "London";

 }



}



// Создаем объект класса Coor:

$object = new Coor;

// Для инициализации объекта сразу вызываем метод:

$object->Init();

?>

Главное не забыть вызвать функцию сразу после создания объекта, либо вызвать какой-нибудь метод между созданием (оператор new) объекта и его инициализацией (вызовом Init).

Для того, чтобы PHP знал, что определенный метод нужно вызывать автоматически при создании объекта, ему нужно дать имя такое же, как и у класса (Coor):

function Coor ($name)

$this->name = $name;

$this->city = "London";

}

Метод, инициализирующий объект, называется конструктором. Однако, PHP не имеет деструкторов, поскольку ресурсы освобождаюся автоматически при завершении работы скриптов.

Обращение к элементам классов

Обращение к элементам классов осуществляется с помощью оператора :: "двойное двоеточие". Используя "двойное двоеточие", можно обращаться к методам классов.

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

<?php

class {

     function 
example() {

         echo 
"Это первоначальная функция A::example().<br>";

     }

}



class 
extends {

     function 
example() {

         echo 
"Это переопределенная функция B::example().<br>";

        
A::example();

     }

}



// Не нужно создавать объект класса A.

// Выводит следующее:

// Это первоначальная функция A::example().

A::example();



// Создаем объект класса B.

$b = new B;



// Выводит следующее: 

//   Это переопределенная функция B::example().

//   Это первоначальная функция A::example().

$b->example();

?>

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

 

Ссылки в PHP

 

 

Ссылки в PHP

Хотя в PHP нет такого понятия, как указатель, все же существует возможность создавать ссылки на другие переменные. Существует две разновидности ссылок: жесткие и символические (переменные переменные) (первые часто называют просто ссылками). Жесткие ссылки появились в PHP версии 4 (в третьей версии существовали лишь символические ссылки).

Ссылки в PHP - это средство доступа к содержимому одной переменной под разными именами. Они не похожи на указатели языка Си и не являются псевдонимами таблицы символов. В PHP имя переменной и её содержимое - это разные вещи, поэтому одно содержимое может иметь разные имена. Ближайшая аналогия - имена файлов Unix и файлы - имена переменных являются элементами каталогов, а содержимое переменных это сами файлы. Ссылки в PHP - аналог жёстких ссылок (hardlinks) в файловых системах Unix.

Жесткие ссылки в PHP

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

Чтобы создать жесткую ссылку, нужно использовать оператор & (амперсанд). Например:

$a=10;

$b = &$a; // теперь $b — то же самое, что и $a

$b=0; // на самом деле $a=0

echo "b=$b, a=$a"; // Выводит: "b=0, a=0"

Ссылаться можно не только на переменные, но и на элементы массива (этим жесткие ссылки выгодно отличаются от символических). Например:

$A=array('a' => 'aaa', 'b' => 'bbb');

$b=&$A['b']; // теперь $b — то же, что и элемент с индексом 'b' массива

$b=0; // на самом деле $A['b']=0;

echo $A['b']; // Выводит 0

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

$A=array('a' => 'aaa', 'b' => 'bbb');

$b=&$A['c']; // теперь $b — то же, что и элемент с индексом 'c' массива

echo "Элемент с индексом 'c': (".$A['c'].")";

В результате выполнения рассмотренного скрипта, хотя ссылке $b и не было ничего присвоено, в массиве $A создастся новый элемент с ключом c и значением — пустой строкой (мы можем это определить по результату работы echo). То есть, жесткая ссылка на самом деле не может ссылаться на несуществующий объект, а если делается такая попытка, то объект создается.

Примечание: Если убрать строку, в которой создается жесткая ссылка, то будет выведено сообщение о том, что элемент с ключом c не определен в массиве $A.

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

Символические ссылки (переменные переменные)

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

$a=10;

$b=20;

$c=30;

$p="a"; // или $p="b" или $p="c" (присваиваем $p имя другой переменной)

echo $$p; // выводит переменную, на которую ссылается $p, т. е. $a

$$p=100; // присваивает $a значение 100

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

Символические ссылки (переменные переменные) используюся достаточно редко.

Смотрите также: Переменные переменные.

Жесткие ссылки и пользовательские функции

Передача значений по ссылке

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

<?php

function foo(&$var)

{

    
$var++;

}



$a=5;

foo($a);

// $a здесь равно 6

?>

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

Еще один интересный пример:

<?php

function funct(&$string)

{

    
$string .= 'а эта внутри.';

}

$str 'Эта строка за пределами функции, ';

funct($str);

echo 
$str;    // Выведет 'Эта строка за пределами функции, а эта внутри.'

?>

По ссылке можно передавать:


  • Переменные, например foo($a)


  • Оператор new, например foo(new foobar())


  • Ссылки, возвращаемые функцией, например:


<?php
function &bar()
{
    
$a 5;
     return 
$a;
}
foo(bar());
?>

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

<?php
function bar() // Операция & отсутствует
{
    
$a 5;
     return 
$a;
}
foo(bar());

foo($a 5); // Выражение, а не переменная
foo(5); // Константа, а не переменная
?>

Возврат значений по ссылке

Рассмотрим еще одну возможность пользовательских функций PHP - возврат ссылок.

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

<?php
function &find_var($param)
{
    
/* ... код ... */
    
return $found_var;
}

$foo =& find_var($bar);
$foo->2;
?>

В этом примере устанавливается свойство объекта, возвращённого функцией find_var, а не его копии, как было бы без использования ссылок.

Еще один пример возврата значений пользовательской функции по ссылке:

<?php
$= 100;
/* Далее идет функция, которая возвращает ссылку */
function &() {
global $a;
// Возвращаем ссылку на переменную $a
return $a;
}
// Присваиваем ссылку переменной $b
$= &s();
$= 0;
echo $a; // Выводит 0
?>

Удаление ссылок (сброс ссылок)

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

<?php
$a 
1;
$b =& $a;
unset(
$a); 
?>

Этот код не сбросит $b, а только $a.

И все же, жесткая ссылка — не абсолютно точный синоним объекта, на который она ссылается. Дело в том, что оператор Unset(), выполненный для жесткой ссылки, не удаляет объект, на который она ссылается, а всего лишь разрывает связь между ссылкой и объектом.

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

Опять же, можно провести аналогию с вызовом unlink (в Unix).

 

Выражения в PHP

 

 

Выражения в PHP

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

Основными формами выражений являются константы и переменные. Например, если вы записываете "$a = 100", вы присваиваете '100' переменной $a:

$a = 100;

В приведенном примере $a - это переменная, = - это оператор присваивания, а 100 - это и есть выражения. Его значение 100.

Выражением может быть и переменная, если ей сопоставлено определенное значение:

$x = 7;

$y = $x;

В первой строке рассмотренного примера выражением является константа 7, а во второй строке - переменная $x, т.к. ранее ей было присвоено значение 7. $y = $x также является выражением.

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

<?php

function funct ()

{

     return 
5;

}

?>

Исходя из того, что вы хорошо знакомы с концепцией функций (если нет, то прочитайте раздел о пользовательских функциях), вы полагаете, что запись $x = funct() абсолютно эквивалента записи $x = 5, и вы правы. Функции - это выражения, значением которых является то, что возвращает функция. Поскольку funct() возвращает 5, значением выражения 'funct()' является 5. Как правило, функции возвращают не статическое значение, а вычисленное.

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

PHP - это язык, ориентированный на выражения и рассматривающий почти все как выражение. Вернемся к примеру, с которым мы уже имели дело: '$x = 7'. Легко заметить, что здесь присутствуют два значения - значение целочисленной константы '7' и значение переменной $x, также принимающей значение 7. Но на самом деле здесь присутствует и еще одно значение - значение самого присвоения. Само присвоение вычисляется в присвоенное значение, в данном случае - в 7. На практике это означает, что '$x = 7', независимо от того, что оно делает, является выражением со значением 7. Таким образом, запись '$y = ($x = 7)' равносильна записи '$x = 5; $y = 5;' (точка с запятой обозначает конец выражения). Поскольку операции присвоения анализируются справа налево, вы также можете написать '$y = $x = 7'.

Логические выражения

Логические выражения — это выражения, у которых могут быть только два значения: ложь и истина (или, что почти то же самое, 0 и 1). Однако, если говорить более строго, то абсолютно любое выражение может рассматриваться как логическое в "логическом" контексте (например, как условие для конструкции if-else). Ведь в качестве TRUE (истины) может выступать любое ненулевое число, непустая строка и т. д., а под FALSE (ложью) подразумевается все остальное.

Для логических выражений справедливы все свойства логических переменных. Эти выражения чаще всего возникают при применении операторов >, < и == (равно), || (логическое ИЛИ), && (логическое И), ! (логическое НЕ) и других. Например:

$a = 10<5; // $a=false

$a = $b==1; // $a=true

$a = $b>=1&&$b<=10 // $a=true, если $b в пределах от 1 до 10

$a = !($b||$c)&&$d; // $a=true, если $b и $c ложны, а $d — истинно

Как осуществляется проверка истинности той или иной логической переменной? Точно так же, как и любого логического выражения:

$b = $a>=1&&$a<=10; // присваиваем $b значение логического выражения

if($b) echo "a в нужном диапазоне значений";

Подробнее о логических операциях смотрите здесь

Строковые выражения

Строки в PHP — одни из самых основных объектов. Они могут содержать текст вместе с символами форматирования или даже бинарные данные.

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

$a="Это текст";

Подробно о строках в PHP смотрите здесь

 

Операторы присвоения в PHP

 

 

Операторы присвоения в PHP

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

Результатом выполнения оператора присвоения является само присвоенное значение. Таким образом, результат выполнения $a = 3 будет равен 3. Это позволяет использовать конструкции вида:

<?php



$a 
= ($b 4) + 5// результат: $a установлена значением 9, переменной $b присвоено 4.



?>

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

<?php



$a 
3;

$a += 5// устанавливает $a значением 8, аналогично записи: $a = $a + 5;

$b "Hello ";

$b .= "There!"// устанавливает $b строкой "Hello There!",  как и $b = $b . "There!";



?>

Обратите внимание, что присвоение копирует оригинальную переменную в новую (присвоение по значению), таким образом все последующие изменения одной из переменных на другой никак не отражаются. Начиная с PHP 4, также поддерживается присваивание по ссылке, используя синтаксис $var = &$othervar; 'Присвоение по ссылке' означает, что обе переменные указывают на одни и те же данные и никакого копирования не происходит. Подробно о ссылках вы можете узнать здесь.

 

Константы в PHP

 

 

Константы в PHP

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

Константой называется именованная величина, которая не изменяется в процессе выполнения программы (скрипта).

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

В РНР константы определяются функцией define(). Эта функция имеет следующий формат:

define ($name, $value, $case_sen), где:



$name - имя константы;

$value - значение константы;

$case_sen - необязательный параметр логического типа,

указывающий, следует ли учитывать регистр букв (true) или нет (false).

Пример определения и использования констант в PHP:

<?php

define("pi",3.14,true);

echo pi;

// Выводит 3.14

?>

Если параметр $case_sen равен true, то интерпретатор будет учитывать регистр символов при работе с константой. Обратите внимание, что константы используются без предваряющего знака $.

Различия между константами и переменными:


  • У констант нет приставки в виде знака доллара ($);


  • Константы можно определить только с помощью функции define(), а не присваиванием значения;


  • Константы могут быть определены и доступны в любом месте без учета области видимости;


  • Константы не могут быть определены или аннулированы после первоначального объявления; и


  • Константы могут иметь только скалярные значения.


Проверка существования констант

Для проверки существования константы можно использовать функцию defined(). Данная функция возвращает true, если константа объявлена. Приведем пример:

<?php
// Объявляем константу pi
define("pi",3.14,true);
if (defined("pi")==true) echo "Константа pi объявлена!";
// Скрипт выведет 'Константа pi объявлена!'
?>

Предопределенные константы PHP

В PHP существуют следующие предопределенные константы:

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

Есть пять предопределенных констант, которые меняют свое значение в зависимости от контекста, в котором они используются. Например, константа __LINE__ зависит от строки в скрипте, на которой эта константа указана. Специальные константы нечувствительны к регистру и их список приведен ниже:


Имя

Описание

__LINE__

Текущая строка в файле.

__FILE__

Полный путь и имя текущего файла.

__FUNCTION__

Имя функции. (Добавлена в PHP 4.3.0.)

__CLASS__

Имя класса. (Добавлена в PHP 4.3.0.)

__METHOD__

Имя метода класса. (Добавлена в PHP 5.0.0)

Дополнительно

» Полный список стандартных констант PHP
» Список объявленных в ядре PHP констант