Php save settings to file

How to read and write INI files in PHP?

INI files are simple text files with a basic structure consisting of sections, property and value. The INI files can be used across different platform which is a great advantage as a single INI file can be used in various versions of the same application for various platforms.

INI files are used to store configurations for applications in a manner of property = value. Values can be single or one dimensional array. Also sections can be used to group same type of configurations. The last thing is comments, we can write comments in INI files. Comments in INI files starts with ; (semicolon)

Sample INI File

Following is a sample INI files which has comments, sections, property and values.

; this is our configuration file for the app that doesn't even exist :P [App Config] name = "Unborn Application" version = "1.0.C" [Authentication] allow registration = 1 allow facebook_registration = 1 allow gmail_registration = 0 [Commenting] allow commenting = 1 allow anonymous = "some data here" [paths] paths[root] = '/' paths[uploads] = "/contents/uploads"

Syntax for INI Files

  1. Use semicolon (;) for comments
  2. Section names must be inside square brackets []
  3. Each property should start at new line followed by an equal which is followed by value of the property. Such as, property = value
  4. String values of properties should be inside single or double quotes
  5. Numeric values should not be inside quotes
  6. Arrays can be indexed; such as paths[root] or non-indexed such as paths[]. If non-indexed, numeric indexes will be placed in result as usual
  7. Only supports one dimensional arrays
Читайте также:  Вывод массива массивов java

Reading an INI File in PHP

Okay so to read this INI file in PHP, just make a call to the function parse_ini_file() as follows

Here, the first parameter is the path to the INI files and the second parameter indicates to include sections in the output which is by default false. However the output of the $config array would like following

Array ( [App Config] => Array ( [name] => "Unborn Application" [version] => "1.0.C" ) [Authentication] => Array ( [allow registration] => 1 [allow facebook_registration] => 1 [allow gmail_registration] => 0 ) [Commenting] => Array ( [allow commenting] => 1 [allow anonymous] => "some data here" ) [paths] => Array ( [paths] => Array ( [root] => "/" [uploads] => "/contents/uploads" ) ) )

If we do not want to use sections in output, then we should not send the second parameter. Anyway, reading is simple but sadly there is no direct function from PHP to modify an existing configuration in an existing INI file or creating a whole new INI file. But no worry, along with the following one there are so many custom functions to write or update configurations in INI file from PHP

Editing or Updating an INI file in PHP

The following function consider that you have already parsed configuration from the INI file and now you have the configuration in an array. You modify the configuration array as you want then you send the array to the function to update or rewrite the INI file with the populated configuration array.

function put_ini_file($config, $file, $has_section = false, $write_to_file = true)< $fileContent = ''; if(!empty($config))< foreach($config as $i=>$v) < if($has_section)< $fileContent .= "[$i]".PHP_EOL.put_ini_file($v, $file, false, false); >else< if(is_array($v))< foreach($v as $t=>$m) < $fileContent .= "$i[$t] = ".(is_numeric($m) ? $m : '"'.$m.'"').PHP_EOL; >> else $fileContent .= "$i = ".(is_numeric($v) ? $v : '"'.$v.'"').PHP_EOL; > > > if($write_to_file && strlen($fileContent)) return file_put_contents($file, $fileContent, LOCK_EX); else return $fileContent; >

So, you call the above function like put_ini_file($configArray, “path/to/config.ini”, true);

Читайте также:  Kotlin backend developer otus

However, you don’t send the 3rd parameter as true if you have no section in your configuration in INI, just send the first two parameters.

Источник

Самые быстрые настройки для PHP-скриптов

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

  • INI-файлы
  • PHP-скрипты
  • XML-файлы
  • Текстовые файлы
  • Файлы с сериализованными данными
  • Вне конкурса — PHP-скрипты с define’ами
  • JSON-файлы NEW!
  • Как можно быстрее загрузить настройки из файла
  • Вернуть массив настроек в виде «ключ» => «значение»
  • Конфигурационный файл содержит 10, 100 или 1000 конфигурационных параметров, представляющих собой короткие строки
  • Конфигурация читается 1000 раз подряд, замеряется время работы в секундах

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

Правда, необходимо сделать небольшое уточнение по поводу программного обеспечения сервера. Использовался реальный веб-сервер, в момент низкой загрузки. Соответственно, конфигурация сервера «боевая»: Linux Debian Lenny, много памяти и RAID1-массив жестких дисков. PHP серии 5.2.x (не самый последний, врочем) с eAccelerator’ом. На время тестов отключался Zend Optimizer, чтобы тесты были более «чистыми», что минимально повлияло на результаты. Тесты без eAccelerator тоже проводились, но, как ни странно, сильно на распределение сил это не повлияло. Причина, на мой взгляд, кроется в том, что eAccelerator настроен на дисковое кэширование опкодов PHP и на сравнение времени модификации файлов, что «съедает» определенное количество времени — хотя и приносит определенные бонусы.

INI-файлы

Результаты: 0.015, 0.086, 0.784

Пример:
x1 = 1
x2 = 2
x3 = 3

Скрипт:
function config ( $file ) <
return parse_ini_file ( $file );
>

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

PHP-скрипты

Результаты: 0.029, 0.111, 0.902

Пример:
return array (
‘x1’ => ‘1’,
‘x2’ => ‘2’,
‘x3’ => ‘3’,
);
?>

Скрипт:
function config ( $file ) <
return include ( $file );
>

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

Обратите внимание на то, что этот вариант стабильно проигрывает INI-файлам, хоть и не очень значительно. Что ж, это компенсируется тем, что в настройках можно использовать PHP-выражения, что позволяет сделать конфиги максимально гибкими.

XML-файлы

Результаты: 0.062, 0.385, 3.911

Пример:

1
2
3

Скрипт:
function config ( $file ) <
$r = array ();
$dom = new DOMDocument ;
$dom -> load ( $file );
foreach ( $dom -> firstChild -> childNodes as $node ) <
if ( $node -> nodeType == XML_ELEMENT_NODE ) <
$r [ $node -> nodeName ] = $node -> firstChild -> nodeValue ;
>
>
return $r ;
>

Недостаток очевидный: очень маленькая скорость работы, в несколько раз медленнее, чем другие варианты. Чтобы проверить, не слишком ли медленная PHP-часть этого кода, я попробовал сделать return сразу после загрузки XML-документа (то есть, фактически, конфигурационные параметры не возвращались). Это ускорило процесс всего приблизительно в два раза. Что подтвердило общий вывод.

Результаты: NEW! 0.047, 0.276, 2.791

Скрипт: NEW!
function config ( $file ) <
$r = array ();
foreach ( simplexml_load_file ( $file ) as $k => $v ) <
$r [ $key ] = strval ( $v );
>
return $r ;
>

С помощью SimpleXML получается, конечно, быстрее. Но не настолько, чтобы претендовать на лидерство.

Текстовые файлы

Результаты: 0.034, 0.250, 2.369

Пример:
x1 1
x2 2
x3 3

Скрипт:
function config ( $file ) <
$r = array ();
if ( $F = fopen ( $file , «r» )) <
while (( $line = fgets ( $F )) !== false ) <
list ( $k , $v ) = explode ( «\t» , $line , 2 );
$r [ trim ( $k )] = trim ( $v );
>
fclose ( $F );
>
return $r ;
>

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

Результат: NEW! 0.036, 0.250, 2.213

Скрипт: NEW!
function config ( $file ) <
$r = array ();
foreach ( explode ( «\n» , file_get_contents ( $file )) as $line ) <
list ( $k , $v ) = explode ( «\t» , $line , 2 );
$r [ trim ( $k )] = trim ( $v );
>
return $r ;
>

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

Файлы с сериализованными данными

Результаты: 0.011, 0.041, 0.309

Пример:
a:3:

Скрипт:
function config ( $file ) <
return unserialize ( file_get_contents ( $file ));
>

Наименее удобочитаемый конфигурационный файл — но при этом самый быстрый результат.

PHP-скрипты с define’ами

Результаты: 0.045, 0.252, 2.404

Пример:
define(«x1», «1»);
define(«x2», «2»);
define(«x3», «3»);
?>

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

JSON-файлы NEW!

Результаты: 0.015, 0.057, 0.495

Пример:

Скрипт:
function config ( $file ) <
return json_decode ( file_get_contents ( $file ) , true );
>

JSON ворвался в нашу жизнь. Его реализация в PHP позволила даже обогнать одного из лидеров, INI-файлы, но немного уступает встроенной сериализации PHP. Одно замечание: приведенный код возвращает не массив, а stdClass object.

Выводы

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

Если Вы серьезный человек — то избегайте прямого чтения текстовых файлов, особенно с большими объемами. Вместо этого Вам вполне подойдут JSON-файлы или INI-файлы, тем более, что скрипты станут работать быстрее.

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

Настройки в формате XML — самые медленные. Прежде, чем их использовать, подумайте хорошенько.

Искренне надеюсь, что define’ы никто не использует, поэтому оставляем их обсуждение вне выводов.

Итог

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

Результаты: 0.018, 0.046, 0.317

Оптимально с точки зрения гибкости и скорости, на мой взгляд.

А вот и сам скрипт:
function config ( $file ) <
$file_dat = «$file.dat» ;
if (! file_exists ( $file_dat ) || filemtime ( $file_dat ) filemtime ( $file )) <
$r = include ( $file );
if ( $F = fopen ( $file_dat , «w» )) <
fwrite ( $F , serialize ( $r ));
fclose ( $F );
>
> else <
$r = unserialize ( file_get_contents ( $file_dat ));
>
return $r ;
>

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

P.S. PHP-код в статье не самый хороший. Я писал его, преследуя две цели: краткость и скорость работы. Поэтому отсутствуют комментарии, длинные имена переменных и различные проверки. Кроме того, большая часть кода работает под PHP 4 и 5 без проблем (кроме, конечно, XML). Надеюсь, это не вызовет излишнего накала страстей.
P.P.S. В сравнение добавлен код JSON.
P.P.P.S. Добавлены небольшие ремарки по поводу железа и программного обеспечения. Без них, согласен с авторами комментариев, было как-то не так.

Источник

Оцените статью