Я на форуме в первые и вообще из меня программист не очень. Так что попрошу ногами меня не бить, а лишь указать мне на ошибки (За этим я сюда пришёл). Мне этот класс нужен для управления конфигурацией, языковыми пакетами и ещё всякой ерундой, но мне кажется что он слегка кривоват. А вот и сам класс ini.class.php: Код (PHP): <?php // Класс для работы с .INI файлами class INI { // Парсит файл и возвращает массив public static function parse($path){ if(!file_exists($path)) { throw new Exception('INI файл: ' . $path . ', не существует!'); } return parse_ini_file($path); } // Получает значение элемента по ключу public static function get($path, $key) { $array = INI::parse($path); if(!isset($array[$key])){ $array[$key] = $key; file_put_contents($path, "\n$key = \"$key\"", FILE_APPEND); } return $array[$key]; } // Обновляет значение элемента по ключу public static function upgrade($path, $key, $value) { if(!file_exists($path)) { throw new Exception('INI файл: ' . $path . ', не существует!'); } $array = INI::parse($path); $array[$key] = $value; $current = ""; foreach ($array as $key => $value) { $current .= "\n$key = \"$value\""; } file_put_contents($path, $current); } // Удаляет элемент public static function remove($path, $key) { if(!file_exists($path)) { throw new Exception('INI файл: ' . $path . ', не существует!'); } $array = INI::parse($path); unset($array[$key]); $current = ""; foreach ($array as $key => $value) { $current .= "\n$key = \"$value\""; } file_put_contents($path, $current); } } Добавлено спустя 25 минут 58 секунд: Ребят пожалуйста не проходите мимо. Я думаю оставить комментарий не кого не затруднит
Да тут применять нечего Некий config.ini: Код (Text): param1 = "value1" param2 = "value2" param3 = "value3" Наш PHP: Код (PHP): // Подключаем класс include("ini.class.php"); // Выводим значение param2 echo INI::get("config.ini", "param2"); // Изменяем значение param1 INI::upgrade("config.ini", "param1", "NEWvalue"); // Удаляем param3 INI::remove("config.ini", "param3"); Я это собираюсь использовать в основном в шаблонизаторе для локализации.
для локализации? gettext уже придумали. с именованием методов каша полная. гет гетом но для записи почему-то вдруг апгрейд. а почему тогда для гета не выбрано имя типа фэтч или рид? или популейт даже. апгрейд тоже для установки значения не особо. сэт же. не? файл постоянно дергается. то есть в приведенном "примере" он будет загружен и распашрен три раза. а чо его в памяти-то не оставить? если два процесса захотят сделать апргрейд или ремув то кто победит? где защита от состояния гонки? на поиск файла ты исключение кидаешь а на работу с ним - нет. а если синтаксис содержимого - инвалидный? а если не удалось прочитать (ну правов не хватило например или ТЫ ЧИТАЕШЬ ДИРЕКТОРИЮ)? а если не удалось записать? а если ты пишешь в ДИРЕКТОРИЮ? в общем так себе работа. сотри.
Мне с INI удобней работать, и создание языковых пакетов гораздо проще выходит. Да и с конфигом можно поработать. Я в английском не силён. Имена как нибудь подправлю. Я не использую этот класс как в примере. Класс INI подгружается ядром при вызове. А этот класс вызывается другими классами, а в них уже есть некая система кеширования. Я лучше всё переделаю.
в смысле с конфигом? инифайлы для пхп-сайта? в массиве храни. он кэшируется зендом. глупость какая. если у тебя этот класс на низком уровне при чтении ключа всегда читает, при записи и удалении всегда читает и записывает - то ты на уровне выше не реализуешь кэширование. ну или у тебя эти высокоуровневые утилиты сами записывают в файл данные хранящиеся в кэше? тогда зачем этот класс нужен?
Я хочу что то своё. Нет из них идёт обращение к классу, только когда нужно. С кешем немного сглупил, надо будет в INI классе парсинг убить. Для укорачивания кода. Типо набора функций. Добавлено спустя 24 минуты 39 секунд: Я даже не представляю как это реализовать. Можешь подсказать? То есть надо добавить проверок? А это не скажется на скорости.
Не прохожу мимо, даже зарегался для этого) По коду есть замечания, кто вас научил при каждом Get, открывать файл и парсить его? Это очень плохой пример. Парсить файл нужно однократно, а не по каждому чиху. Рекомендаця 1: В начале своих скриптов делайте: Код (PHP): <?php INI::Load("config1.ini"); INI::Load("config2.ini"); ?> В конце делайте: Код (PHP): <?php INI::Save(); ?> Использование: Код (PHP): <?php $val = INI::Get("config1.ini", "key"); ?> Сам класс реализуйте так: Метод INI::Load(ini_name) - загружает файл и парсит его, забивая в массив данные, и сам же запихает полученый массив в общий массив файлов, ключ у него ini_name, данные как вы поняли полученные из файла. Тем самым вы сможете использовать несколько файлов, не загружая их на каждый чих и пых. Метод INI::Get(ini_name, key) - Очень прост, проверяет есть ли загружен ini_name, нет - выбрасывает исключение, есть - по ключу выдаёт значение из нужного массива. Метод INI::Save() - Проходит по всем загруженным ini файлам, и сохраняет из обратно, за один раз. В добавок: Можно еще сделать методы Set и Make, что бы на лету создавать ini файлы. Метод INI::Make(ini_name) - Просто создает во внутреннем массиве новый с ключем ini_name, и потом уже по этому имени можно делать INI::Set(ini_name, key, value), ну и в конце скрипта INI::Save() Рекомендация 2: И если честно INI файл для локализации так себе, практичней соорудить что то такое: Код (PHP): <?php $LOCALISATION = array( 'ru' => array( 'test' => 'Тест' ), 'en' => array( 'test' => 'Test' ) ); //Ну и для удобного извлечения function Get($loc, $key) { return $LOCALISATION[$loc][$key]; } ?> Добавлено спустя 7 минут 31 секунду: Что то аж в голос посмеялся) А то что вы дергаете файл на каждый Get-Set по вашему на скорость не влияет? Добавлено спустя 9 минут 18 секунд: Дополнение к рекомендации 2: Если же переживаете за скорость, то можно реализовать класс LoadLoc и метод Init (или Load как хотите так и назовите), который нужно вызывать в начале скрипта, с именем локализации (ru,en), и потом из него же LoadLoc::Get(key) выдавать из загруженной локализации значения по ключу, получится что у вас всегда будет загружена нужная локализация и ничего больше. В итоге вам нужно создать по одному php файлу на каждую локализацию, и один для загрузки нужной локализации. От себя в добавок: Возможно меня побьют, но php устарел, и лучше использовать что то более новое, например: Golang, с ним за скорость можно не переживать. PHP, JavaScript, SQL и другой код пишите внутри тегов Код ( (Unknown Language)): [b]php][/b]Тут код[b][/[/b][b]code][/b][/color]
Я долго боролся с локализацией, для более простой разработки шаблона. Приведённый пример не очень, много прописывать кода надо. У меня происходит так: Я вызываю функцию в шаблоне _e($key) выводит, _r($key) возвращает. если в ini нету значения с ключом оно создаётся, то есть не надо допиливать всё время файл или массив. А только в конце создания шаблона зашёл отредактировал перевод и всё. Кусок моего шаблона: Код (PHP): <div class="container"> <?php _e('Какой то текст'); ?> </div> <?php $this->foot() ?> Кусок php: Код (PHP): // Алиасы Langage::get(); function _r($string) { return Langage::get($string); } function _e($string) { echo Langage::get($string); } Насчёт INI класса сделаю как вы сказали. Только INI::Set(ini_name, array(key => value)) так меньше кода получается. PHP, JavaScript, SQL и другой код пишите внутри тегов Код ( (Unknown Language)): [b]php][/b]Тут код[b][/[/b][b]code][/b][/color]
Зацените ini.class.php V2 Код (PHP): <?php // Класс для работы с .INI файломи, на них строиться конфигурация class INI { private static $cache = array(); // Парсит файл и возвращает масив public static function Load($path) { if(!file_exists($path)) { static::$cache[$path] = array(); } else { static::$cache[$path] = parse_ini_file($path); } } // Получает значение элемента по ключу public static function Get($path, $key) { if(!isset(static::$cache[$path])) { static::Load($path); } $array = static::$cache[$path]; if(!isset($array[$key])) return false; return $array[$key]; } // Редактирование элемента public static function Set($path, $new = array()) { if(!isset(static::$cache[$path])) { static::Load($path); } $array = static::$cache[$path]; foreach ($new as $key => $value) { $array[$key] = $value; } static::$cache[$path] = $array; } // Удаляет элемент public static function Remove($path, $array) { if(!isset(static::$cache[$path])) { static::Load($path); } foreach ($array as $key) { unset(static::$cache[$path][$key]); } } // Очищает файл public static function Clear($path) { if(isset(static::$cache[$path])) { static::$cache[$path] = array(); return true; } else { return false; } } // Сохраняет все изменения public static function Save() { foreach (static::$cache as $path => $content) { $current = ""; foreach ($content as $key => $value) { $current .= "\n$key = \"$value\""; } file_put_contents($path, $current); } } } Описание функций: INI::Load("Путь к файлу") - Подгружает файл в кэш, если нету файла создаёт его. Использовать её стоит в начале, ей можно вообще не пользоваться, она автоматически вызывается.[/*:m] INI::Get("Путь к файлу", "Ключ") - Возвращает значение по ключу.[/*:m] INI::Set("Путь к файлу", array("Ключ1" => "Значение1", "Ключ2" => "Значение2")) - Добавляет новые значения или изменяет.[/*:m] INI::Remove("Путь к файлу", array("Ключ1", "Ключ2") - Удаляет значения.[/*:m] INI::Clear("Путь к файлу") - Полностью очищает файл, не знаю где это может пригодиться, просто решил написать.[/*:m] INI::Save() - Сохраняет изменения. Эту функцию следует вызывать в самом низу.[/*:m][/list:u] Пример: Код (PHP): include('ini.class.php'); $file = 'file.ini'; INI::Set($file, array( 'param1' => 'value1', 'param2' => 'value2', 'param3' => 'value3' )); INI::Save(); Код выше создаёт файл file.ini, с содержанием: Код (Text): param1 = "value1" param2 = "value2" param3 = "value3" Осталось добавить несколько проверок от дурака)))
Всё делается гораздо проще - делается не статический, а нормальный класс, чтоб экземпляры создавать, и в экземпляре ваш файл держать. И писать удобно. Код (Text): $conf = new INI("filename.ini"); $param1 = $conf->get("param1"); // Или даже через магию php $param2 = $conf->param2; // Или через реализацию ArrayAccess $param3 = $conf["param3"]; $conf->set("param4", "value"); $conf->param5 = "value"; $conf["param6"] = "value"; А эти статические классы меня всегда так раздражают. Какое они преимущество дают?
geone Состояние гонки возникает, когда два потока доступа к общей переменной в то же время. Оба потока считывают одно и тоже значение переменной. Оба потока производят какие-либо действия со значением и далее возникает гонка за то, кто последним сможет записать новое значение. Поток, который запишет значение последним перезапишет значение, которое записал предыдущий поток. Так же и с файлами.
Вдумайтесь в само задание, никто не даёт пользователям права писать что то, потоки могу только читать, запись нужна лишь для отладки. Добавлено спустя 1 минуту 41 секунду: В данный момент лучше использовать статику, во первых - статика производительней, во вторых - в данном случае не нужно писать никому ненужный singleton Добавлено спустя 34 секунды: Вот, это уже другое дело.
повторюсь: 1. ловить эксепшены лучше в функциях, нафик их кидать вообще в данном случае - мне не понятно. 2. лучше вообще не писать ини файл =) а делать это руками, когда надо. Если что-то часто меняется - есть бд.
Причём здесь синглтон, если файлов конфигурации много, и они грузятся в память? Один файл - один экземпляр класса. По поводу производительности - не верю, что это настолько критически заметно. Если производительнее, пишите обычные функции, без классов.
Вы понимаете что он грузит только нужные файлы, статика это те же функции, просто вгруппе. Добавлено спустя 1 минуту 18 секунд: Вы издеваетесь? хранить локализацию в бд??? Это новый уровень извращения.
А мой вариант с конструктором будто бы будет по всему диску искать... Ладно, если вам нравится писать Код (Text): INI::get("path_to_ini_file", "param"); вместо Код (Text): $conf->param пишите
С таким подходом вам и голанг не поможет ) Го не серебренная пуля, там точно так же можно написать тормозящее, жрущее память приложение.
Если говорить про Го, то это уже другое дело, и архитектура там другая. Я никогда не понимал, зачем городить миллион классов на миг. php - Это как бабочка, которая живет всего день, но строит себе дом, и после постройки сразу умирает.
миллион классов городят в пхп не потому, что это круто. Причина куда смешнее. Найти хорошего пхпшника сложно. А найти какого-нить джависта - проще. Джависта пересаживают на пхп, он тащит свой привычный уклад с собой.
Я про всевозможные фреймворки, их везде используют, для псевдо облегчения работы, но в итоге уменьшают скорость приложения
Очень просто. Покажите мне на го: 1. Вменяемую систему управления зависимостями, не так что бы всё скачалось в src/, а с версиями, под каждый проект и без костылей. 2. Нормальный фреймворк с абстракцией над базами данные, кэшированием, файловой системой (в т.ч. облачной) 3. Реализации OAuth для всех популярных и не очень провайдеров, работе с различными типами файлов, очередями и прочими необходимыми вещами. При этом все должно быть с вменяемой документацией, code style и сообществом. Я уж молчу, раз мы говорим о вебе, хотя бы одну CMS с нормальным функционалом. Этого нет на Го и даже на ноде, в отличии от PHP. К чему всё это? К тому что прежде всего важна скорость и удобство разработки, а не экономия на спичках и красивых графиках, отсюда и миллион классов с абстракциями и интерфейсами на один миг ) p.s. го крут, как и нода. Просто нужно понимать в чем и применять инструмент по необходимости.