Сделай Сам Свою Работу на 5

Функции работы с графикой в PHP





 

В PHP есть много функций на все случаи жизни. Работа с графикой – не исключение. Веб-мастерам бывает необходимо динамически создавать и/или изменять рисунки на своих страницах. Это требуется в тех случаях, когда изображения несут не исключительно декоративную функцию, а содержат некую полезную информацию. С использованием PHP решение этой задачи становится более чем тривиальным – достаточно подключить модуль расширения GD.

Загрузить модуль GD можно по адресу www.boutell.com/gd. Для его подключения необходимо убрать знак комментария в строке extension=php_gd.dll (для сервера с ОС Windows; в случае Unix-систем расширение файла может быть другим) в php.ini и перезапустить веб-сервер. Различные версии GD могут работать с разными форматами графических файлов. Так, при использовании библиотеки версии 1.6 и ниже можно создавать изображения в форматах JPEG, GIF и SWF, но не PNG. Более новые версии позволяют использовать PNG, но отказываются поддерживать формат GIF из лицензионных соображений. Все приведенные ниже примеры будут работать при использовании GD версии 2.0.1 или выше.

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



http://www.php.net/manual/ru/ref.image.php

 

 

Тема 5. Файлы и директории в PHP. Сессии в PHP

 

Работа с файлами

 

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

 

File_exists()

 

bool file_exists (string filename)

 

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

 

if ( !file_exists("somefile.txt") ) exit("Указанный файл не существует");



 

Функция действует только на локальных файлах. Вот некоторые правила описания пути к файлу:

· filename – Просто указание имени файла означает, что он находится в текущей директории.

· ./files/filename – Файл содержится в папке files, находящейся в текущей директории. Длина цепочки из папок не ограничена.

· ../filename Файл лежит в предыдущей директории. Каждый знак ../ расценивается как возврат в родительскую директорию.

· ../files/filename Файл находится в папке files, которая лежит в предыдущей директории.

 

Filesize()

 

int filesize (string filename)

 

Функция определяет размер файла и возвращает его в байтах. Пустой файл содержит 0 байт.

 

File()

 

array file (string filename [, int use_include_path [, resource context]])

 

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

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

 

$text_file = implode("", file("somefile"));

echo $text_file;

 

Readfile()

 

int readfile (string filename [, bool use_include_path [, resource context]])

 

Функция readfile читает содержимое указанного файла и возвращает число символов в файле (или количество байт, кому как нравится, так как один символ равен одному байту). Но в отличие от file, эта функция не предусматривает присваивание прочитанного содержимого файла переменной, а выводит его напрямую в выходной поток.



 

Пример 5.1.4.1:

 

$bytes = readfile ("somefile");

echo "Итого - ".$bytes." символов";

 

 

Fopen()

 

resource fopen (string filename, string mode [, bool use_include_path [, resource zcontext]])

 

fopen() закрепляет именованый ресурс, указанный в аргументе filename, за потоком. Если filename передан в форме "scheme://...", он считается URL'ом и PHP проведёт поиск обработчика протокола (также известного как "обвёртка") для этой схемы. Если ни одна обвёртка не закреплена за протоколом, PHP выдаст замечание чтобы помочь вам отследить потенциальную проблему в вашем скрипте и продолжит выполнение, будто filename указывает на обыкновенный файл.

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

Если PHP решил, что filename указывает на зарегистрированный протокол и этот протокол зарегистрирован как сетевой URL, PHP проверит состояние директивы allow_url_fopen. Если она выключена, PHP выдаст предупреждение и вызов fopen закончится неудачей.

Начиная с версии PHP 4.3.2, бинарный режим является режимом по умолчанию для всех платформ, которые различают бинарный и текстовый режимы. Если у вас возникли проблемы после обновления, попробуйте использовать флаг 't' в качестве обходного пути до тех пор, пока вы не измените свои скрипты для достижения большей портируемости, как отмечено выше.

Параметр mode указывает тип доступа, который вы запрашиваете у потока. Он может быть одним из следующих:

 

- 'r' Открывает файл только для чтения; помещает указатель в начало файла.

- 'r+' Окрывает файл для чтения и записи; помещяет указатель в начало файла.

- 'w' Открывает файл только для записи; помещает указатель в начало файла и обрезает файл до нулевой длинны. Если файл не существует - пробует его создать.

- 'w+' Открывает файл для чтения и записи; помещает указатель в начало файла и обрезает файл до нулевой длинны. Если файл не существует - пробует его создать.

- 'a' Открывает файл только для записи; помещает указатель в конец файла. Если файл не существует - пытается его создать.

- 'a+' Открывает файл для чтения и записи; помещает указатель в конец файла. Если файл не существует - пытается его создать.

- 'x' Создаёт и открывает только для записи; помещает указатель в начало файла. Если файл уже существует, вызов fopen() закончится неудачей, вернёт FALSE и выдаст предупреждение уровня E_WARNING. Если файл не существует, попытается его создать. Это эквивалентно указанию флагов O_EXCL|O_CREAT для внутреннего системного вызова open(2). Эта опция поддерживается начиная с версии PHP 4.3.2 и выше, и работает только для локальных файлов.

- 'x+' Создаёт и открывает для чтения и записи; помещает указатель в начало файла. Если файл уже существует, вызов fopen() закончится неудачей, вернёт FALSE и выдаст предупреждение уровня E_WARNING. Если файл не существует, попытается его создать. Это эквивалентно указанию флагов O_EXCL|O_CREAT для внутреннего системного вызова open(2). Эта опция поддерживается начиная с версии PHP 4.3.2 и выше, и работает только для локальных файлов.

 

Разные семейства операционных систем имеют разные соглашения относительно окончания строк. Когда вы пишете текст и хотите вставить разрыв строки, вы должны использовать правильный(-ые) символ(ы) для вашей операционной системы. Системы семейства Unix используют \n в качестве символа конца строки, системы семейства Windows используют \r\n в качестве символов окончания строки и системы семейства Macintosh используют \r в качестве символа конца строки.

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

Windows предлагает флаг режима текстовой трансляции ('t'), который автоматически переведёт \n во время работы с файлом. И наоборот - также вы можете использовать 'b' чтобы принудительно включить бинарный (двоичный) режим, в котором ваши данные не будут преобразовываться. Чтобы использовать эти режимы, укажите 'b' или 't' в качестве последней буквы параметра mode.

Так как установка флага трансляции по умолчанию зависит от SAPI и версии PHP, которую вы используете, рекомендуем явно задавать указанный флаг из соображений портируемости. Вы должны использовать режим 't' если вы работаете с текстовым файлом и использовать \n для разделения для обозначения конца строки в вашем скрипте, при этом не беспокоясь за читаемость ваших файлов в других приложениях типа "Блокнота". В противном случае вам следует использовать флаг 'b'.

Если вы явно не укажете флаг 'b' во время работы с бинарными файлами, вы можете столкнуться со странной порчей ваших данных, включая испорченные файлы изображений и странные проблемы с символами \r\n.

Из соображений портируемости, настоятельно рекомендуется всегда использовать флаг 'b' при открытии файлов с помощью fopen().

Кроме того, из соображений портируемости, также настойчиво рекомендуется переписать старый код, который полагается на режим 't', чтобы вместо этого он использовал правильные окончания строк и режим 'b'.

 

Необязательный третий параметр use_include_path может быть установлен в '1' или TRUE, если вы также хотите провести поиск файла в include_path.

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

 

Пример 5.1.5.1:

 

<?

$handle = fopen("/home/rasmus/file.txt", "r");

$handle = fopen("/home/rasmus/file.gif", "wb");

$handle = fopen("http://www.example.com/", "r");

$handle = fopen("ftp://user:password@example.com/somefile.txt", "w");

?>

 

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

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

 

Пример 5.1.5.2:

 

<?php

$handle = fopen("c:\\data\\info.txt", "r");

?>

 

При использовании SSL, Microsoft IIS нарушает протокол, закрывая соединение без отправки индикатора close_notify. PHP сообщит об этом как о "SSL: Fatal Protocol Error" в тот момент, когда вы достигнете конца данных. Чтобы обойти это, вы должны установить error_reporting на уровень, исключающий E_WARNING. PHP версий 4.3.7 и старше умеет определять, что на стороне сервера находится проблемный IIS и не выводит предупреждение. Если вы используете fsockopen() для создания ssl:// сокета, вы сами отвечаете за определение и подавление этого предупреждения.

Когда опция safe mode включена, PHP проверяет, имеет ли каталог, с которым вы собираетесь работать, такой же UID (владельца), как и выполняемый скрипт.

 

Fgets()

 

string fgets ( resource handle [, int length] )

 

Возвращает строку размером в length - 1 байт, прочитанную из дескриптора файла, на который указывает параметр handle. Чтение заканчивается, когда количество прочитанных байтов достигает length - 1, по достижении конца строки (который включается в возвращаемое значение) или по достижении конца файла (что бы ни встретилось первым). Если длина не указана, по умолчанию ее значение равно 1 килобайту или 1024 байтам.

В случае возникновения ошибки функция возвращает FALSE.

Наиболее распространенные ошибки:

Программисты, привыкшие к семантике 'C' функции fgets(), должны принимать во внимание разницу в том, каким образом возвращается признак достижения конца файла (EOF).

Указатель на файл должен быть корректным и указывать на файл, успешно открытый функциями fopen() или fsockopen().

 

Пример 5.1.6.1:

 

<?

$handle = fopen("/tmp/inputfile.txt", "r");

while (!feof($handle)) {

$buffer = fgets($handle, 4096);

echo $buffer;

}

fclose($handle);

?>

 

Параметр length стал необязательным, начиная с PHP версии 4.2.0. Если этот параметр опущен, длина строки принимается за 1024. С версии PHP 4.3, отсутствие параметра length будет приводить к чтению потока до конца строки. Если длина большинства строк в файле превышает 8 килобайт, наиболее эффективным решением в отношении ресурсов, используемых скриптом, будет указание максимальной длины строки.

Данная функция может корректно обрабатывать двоичные данные, начиная с версии PHP 4.3. Более ранние версии не обладали этой функциональностью.

Если у вас возникают проблемы с распознаванием PHP окончания строк при чтении файлов на Macintosh-совместимом компьютере или при чтении файлов, созданных на Macintosh-совместимом компьютере, необходимо включить опцию auto_detect_line_endings.

 

Fputs()

 

Это псевдоним функции fwrite

 

int fwrite ( resource handle, string string [, int length] )

 

fwrite() записывает содержимое string в файловый поток handle. Если передан аргумент length, запись остановится после того, как length байтов будут записаны или будет достигнут конец строки string, смотря что произойдёт первым.

 

fwrite() возвращает количество записанных байтов или FALSE в случае ошибки.

Обратите внимание, что если аргумент length указан, то конфигурационная опция magic_quotes_runtime будет проигнорирована и строка string не будет очищена от слешей.

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

 

Пример 5.1.7.1:

 

<?

$filename = 'test.txt';

$somecontent = "Добавить это к файлу\n";

 

// Вначале давайте убедимся, что файл существует и доступен для записи.

if (is_writable($filename)) {

 

// В нашем примере мы открываем $filename в режиме "дописать в конец".

// Таким образом, смещение установлено в конец файла и

// наш $somecontent допишется в конец при использовании fwrite().

if (!$handle = fopen($filename, 'a')) {

echo "Не могу открыть файл ($filename)";

exit;

}

 

// Записываем $somecontent в наш открытый файл.

if (fwrite($handle, $somecontent) === FALSE) {

echo "Не могу произвести запись в файл ($filename)";

exit;

}

 

echo "Ура! Записали ($somecontent) в файл ($filename)";

 

fclose($handle);

 

} else {

echo "Файл $filename недоступен для записи";

}

?>

 

 

Fclose()

 

bool fclose ( resource handle)

 

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

Для иллюстрации связки вышеуказанных функций приведем пример создания простого счетчика посещений (пример 5.1.8.1):

 

<?

$file = fopen("counter.txt", "r");

$c = fgets ($file, 150);

fclose ($file);

$c++;

$file = fopen("counter.txt", "w");

fputs ($file, $c);

fclose ($file);

echo $c;

?>

 

Работа с директориями

 

Тесно связаны с действиями над файлами операции с директориями. Алгоритм работы с ними схож с операциями над файлами: сначала директорию необходимо открыть, выполнить какие-либо действия и, наконец, закрыть её.

 

 

Opendir()

 

resource opendir (string path)

 

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

· . Точка означает открытие текущей директории.

· ./files/ Открытие папки files, находящейся в текущей директории.

· .. Открытие папки на уровень выше текущей.

 

Readdir()

 

string readdir ( resource dir_handle )

 

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

Обратите внимание на способ проверки значения, возвращаемого функцией readdir() в приведенном ниже примере. В этом примере осуществляется проверка значения на идентичность (выражения идентичны, когда они равны и являются значениями одного типа) значению FALSE, поскольку в ином случае, любой элемент каталога, чье имя может быть выражено как FALSE, остановит цикл (например, элемент с именем "0").

 

Пример 5.2.2.1:

 

<?

// Обратите внимание, что оператор !== не существовал до версии 4.0.0-RC2

 

if ($handle = opendir('/path/to/files')) {

echo "Дескриптор каталога: $handle\n";

echo "Файлы:\n";

 

/* Именно этот способ чтения элементов каталога является правильным. */

while (false !== ($file = readdir($handle))) {

echo "$file\n";

}

 

/* Этот способ НЕВЕРЕН. */

while ($file = readdir($handle)) {

echo "$file\n";

}

 

closedir($handle);

}

?>

 

Обратите внимание, что функция readdir() также возвращает элементы с именами . и ..

Если вы не хотите получать эти значения, просто отбрасывайте их.

 

Closedir()

 

void closedir (resource dir_handle)

 

Закрываеn директорию, указывая в качестве аргумента идентификатор соединения.

 

 

Chdir()

 

bool chdir (string directory)

 

Делает указанный каталог текущим ("переходит" в него).

 

Upload файлов

 

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

 

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

<input type="hidden" name="MAX_FILE_SIZE" value="30000">

Send this file: <input name="userfile" type="file">

<input type="submit" value="Send File">

</form>

 

При этом в поле action должен быть указан URL вашего php-скрипта, который в дальнейшем будет заниматься обработкой загружаемых файлов. Скрытое поле MAX_FILE_SIZE должно предшествовать полю выбора файла, и содержать максимально допустимый размер файла в байтах. Его назначение – проверка размера файла еще до момента отправки файла на сервер. Это должно избавить пользователя от длительной и безрезультатной загрузки файла на сервер и образования лишнего трафика, но не стоит особо полагаться на это ограничение, так как его легко обойти.

Что происходит, когда пользователь выбрал файл на своем диске, и нажал на кнопку "Send file"? Браузер отсылает файл на сервер, где php-интерпретатор помещает его в свою временную директорию, присваивая ему случайное имя и выполняет скрипт, указанный в поле action.

 

Как должен выглядеть upload.php? Пример 5.3.2:

 

<?

$uploaddir = '/var/www/uploads/';

if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploaddir .

$_FILES['userfile']['name'])) {

print "File is valid, and was successfully uploaded.";

} else {

print "There some errors!";

}

?>

 

При написании скрипта, возникает естественный вопрос: как получить информацию о загруженном файле и достучаться до самого файла. Если вы используете PHP версии 4.1.0 и старше, лучше всего будет обратиться к глобальному массиву $_FILES. Для каждого загруженного файла он содержит хеш-массив, со следующими данными:

· $_FILES['userfile']['name'] - оригинальное имя файла, такое, каким его видел пользователь, выбирая файл;

· $_FILES['userfile']['type'] - mime/type файла, к примеру, может быть image/gif; это поле полезно сохранить, если вы хотите предоставлять интерфейс для скачивания загруженных файлов;

· $_FILES['userfile']['size'] - размер загруженного файла;

· $_FILES['userfile']['tmp_name'] - полный путь к временному файлу на диске;

· $_FILES['userfile']['error'] - Начиная с версии 4.2.0, содержит код ошибки, который равен 0, если операция прошла успешно.

 

Для PHP версии ниже 4.1.0 этот массив называется $HTTP_POST_FILES. Не стоит забывать, что в отличие от $_FILES этот массив не является суперглобальным и при обращении к нему, к примеру, из функции, необходимо явно указывать global $HTTP_POST_FILES;

Если в настройках вашего сервера register_globals=on, будут созданы дополнительные переменные вида $userfile_name, $userfile_type, $userfile_size… Учитывая, что, начиная с версии 4.2.0, в настройках по умолчанию register_globals=off использования этих переменных не рекомендовано, даже если они определены. Лучший способ получения информации о загружаемых файлах – использовать массив $_FILES.

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

 

Настройка сервера

 

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

 

В файле php.ini:

· Если вы хотите узнать, где расположен Ваш php.ini, выполните <?php phpinfo(); ?>

· file_uploads – возможность запретить или разрешить загрузку файлов в целом. По умолчанию On.

· upload_max_filesize – максимальный размер файла, который может быть загружен. Если вам необходимо работать с большими файлами, измените эту настройку. По умолчанию 2М. Не забудьте изменить post_max_size.

· post_max_size – общее ограничение сверху на размер данных, передаваемых в POST запросе. Если вам необходимо работать с большими файлами, или передавать несколько файлов одновременно, измените эту настройку. Значение по умолчанию 8М.

· upload_tmp_dir – временная директория на сервере, в которую будут помещаться все загружаемые файлы. Проверьте, какие на неё выставлены права. Такая директория должна существовать и у пользователя, под которым выполняется Apache, также должны быть права на запись в эту директорию. Если вы работаете с включенным ограничением open_basedir – то временный каталог должен находиться внутри.

 

В файле httpd.conf:

 

· Если вы получили сообщение "POST Method Not Allowed", это означает, что надо искать что-то похожее на следующие директивы, и использовать ключевое слово Allow:

 

<Limit POST >

Order allow,deny

Allow from all

</Limit>

 

· Проблемы с загрузкой бинарных файлов – классический вопрос "почему бьются файлы при upload". В директории, где лежит скрипт, делаем файл .htaccess, в котором пишем: CharsetDisable On. В файл httpd.conf дописать строки:

 

<Location />

CharsetRecodeMultipartForms Off

</Location>

 

Небольшие пояснения, к этому рецепту: вышеописанная проблема, когда загруженные на сервер архивы не распаковываются и картинки не отображаются, может возникать из-за того, что используется веб-сервер Russian Apache. Директива CharsetDisable отключает модуль charset-processing module, т.е. никакой перекодировки при скачивании файлов, находящихся в данной папке, происходить не будет. Директива CharsetRecodeMultipartForms выключает перекодировку данных, переданных методом POST с заголовком Content-Type: multipart/form-data. Т.е. двоичные данные, переданные с такой настройкой, будут оставлены в первоначальном виде, а все остальное наполнение сайта будет перекодировано согласно текущим настройкам сервера.

 

 








Не нашли, что искали? Воспользуйтесь поиском по сайту:



©2015 - 2024 stydopedia.ru Все материалы защищены законодательством РФ.