За последние 24 часа нас посетили 22588 программистов и 1277 роботов. Сейчас ищут 848 программистов ...

Оцените класс для работы с INI файлами

Тема в разделе "Прочие вопросы по PHP", создана пользователем geone, 4 окт 2015.

  1. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    что-то слишком много теоретического внимания одному аспекту всего проекта. Делай уже как хочешь. Если вылезут проблемы - появится опыт и понимание само собой. Что там у тебя следующим номером по программе?
     
  2. geone

    geone Новичок

    С нами с:
    4 окт 2015
    Сообщения:
    139
    Симпатии:
    0
    Я хочу хорошо))
    Проблем вроде нет, уже работает как задумано.
    Сам класс локализации доделать, набраться опыта и закончить MCV а то она мутная какае то и без ЧПУ.
     
  3. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.902
    Симпатии:
    969
    с исключениями всё так когда ты их используешь "грамотно": бросил - поймал-прочитал статус - дальше бросил или другое бросил - и/или выполнил блок финализации и тд и тп. а бросить исключение чтоб его просто поймать на самом верху - тут я с игоряшей соглашусь - фолса будет вполне достаточно для отображения неудачного стечения обстоятельств при попытке чтения файла. потому что ты ловишь-то наверху, где у тебя хэндлер стоит, а не вот тут где ты вызвал метод. ведь не факт что программу нельзя дальше выполнять - локализация дефолтная (инглиш тот же) обязана уже присутствовать и хрен с ней что недоступен какой-то диалект каких-то там туземцев.

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

    geone Новичок

    С нами с:
    4 окт 2015
    Сообщения:
    139
    Симпатии:
    0
    Не угадал, в этом вся фишка если файла нет то он создаётся. А в конце создания шаблона уже редактируешь файл с локализацией.

    Особо не чего не менял, практически всё тоже, и работает также. Думаю на этом всё с INI классом, хотя не знаю...
    Код (PHP):
    1. <?php
    2. // Класс для работы с .INI файломи, на них строиться конфигурация
    3. class INI {
    4.     private static $cache = array();
    5.     
    6.     // Парсит файл и возвращает масив
    7.     public static function Load($path) {
    8.         if(!file_exists($path)) {
    9.             static::$cache[$path] = array();
    10.             return true;
    11.         } else {
    12.             static::$cache[$path] = parse_ini_file($path);
    13.             return static::$cache[$path];
    14.         }
    15.     }
    16.     
    17.     // Получает значение элемента по ключу
    18.     public static function Get($path, $key) {
    19.         if(!isset(static::$cache[$path])) {
    20.             static::Load($path);
    21.         }
    22.         
    23.         $array = static::$cache[$path];
    24.         
    25.         if(!isset($array[$key])) return false;
    26.         return $array[$key];
    27.     }
    28.     
    29.     // Редактирование элемента
    30.     public static function Set($path, $new = array()) {
    31.         if(!isset(static::$cache[$path])) {
    32.             static::Load($path);
    33.         }
    34.         
    35.         $array = static::$cache[$path];
    36.         foreach ($new as $key => $value) {
    37.             $array[$key] = $value;
    38.         }
    39.             
    40.         static::$cache[$path] = $array;
    41.     }
    42.     
    43.     // Удаляет элемент
    44.     public static function Remove($path, $array) {
    45.         if(!isset(static::$cache[$path])) {
    46.             static::Load($path);
    47.         }
    48.         
    49.         foreach ($array as $key) {
    50.             unset(static::$cache[$path][$key]);
    51.         }
    52.     }
    53.     
    54.     // Очищает файл
    55.     public static function Clear($path) {
    56.         if(isset(static::$cache[$path])) {
    57.             static::$cache[$path] = array();
    58.             return true;
    59.         } else {
    60.             return false;
    61.         }
    62.     }
    63.     
    64.     // Сохраняет все изменения
    65.     public static function Save() {
    66.         foreach (static::$cache as $path => $content) {
    67.             $current = "";
    68.             foreach ($content as $key => $value) {
    69.                 $current .= "$key = \"$value\"\n";
    70.             }
    71.             
    72.             $save = file_put_contents($path, $current);
    73.             if($save == false) {
    74.                 return false;
    75.             }
    76.         }
    77.         return true;
    78.     }
    79. }
     
  5. romach

    romach Старожил

    С нами с:
    26 окт 2013
    Сообщения:
    2.904
    Симпатии:
    719
    https://phpbox.info/4iYtT разница конечно есть, но оно того не стоит.
    Нет. К примеру, как только возникнет необходимость хранить состояние, так сразу придется испытать всю боль этого мира )
    Экземпляр класса можно создать лишь однажды и везде обращаться к нему, познайте для себя чудесный мир DI )

    Я не к тому, что это всё обязательно, если вы планируете оставаться на cms-ках и простеньких скриптах, то конечно да, можно и так. Но если вы планируете заняться чем-то более серьезным, то надо менять подход с "мне так удобней", на "почему остальным удобней по другому?". К примеру подход mkramer гораздо более прозрачный, общеупотребимый и к тому же на порядок функциональней. При прочих равных я предпочту работать с ним, чем разбираться в том, что удобно вам.

    p.s. имхо

    Ganzal, согласен. Я похоже просто не так Игоря понял.
     
  6. geone

    geone Новичок

    С нами с:
    4 окт 2015
    Сообщения:
    139
    Симпатии:
    0
    Практически тоже самое реализовано. Если не языка - дефолт русский, даже если нет файла для локализации он создаётся. если нет строки для какой-то локали - такого не может быть, они автоматом добавляются. если встретились одинаковые строки - такого тоже не может быть. И всё это на INI и PHP.
     
  7. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    ой, это точно работа для бд прям. с индексами и уникальными индексами и прочей мутью =)
     
  8. geone

    geone Новичок

    С нами с:
    4 окт 2015
    Сообщения:
    139
    Симпатии:
    0
    Работа с локализацией это точно не для бд.

    Мой langage.class.php:
    Код (PHP):
    1. <?php
    2. // Класс интернализации
    3. class Langage {
    4.      
    5.     private static $langs = array('ru', 'en');
    6.     public static $lang;
    7.     public static $path; 
    8.     
    9.     public static function Load($path) {
    10.         if (!empty($_GET['lang']) && in_array($_GET['lang'], static::$langs)) { 
    11.             setcookie('lang', $_GET['lang']); 
    12.             static::$lang = $_GET['lang']; 
    13.         } elseif (!empty($_COOKIE['lang']) && in_array($_COOKIE['lang'], static::$langs)) { 
    14.             static::$lang = $_COOKIE['lang']; 
    15.         } else { 
    16.             static::$lang = 'ru'; 
    17.         }
    18.         
    19.         static::$path = $path . static::$lang . '.lang.ini';
    20.     } 
    21.     
    22.     public static function Get($string) {
    23.         $val = INI::get(static::$path, $string);
    24.         if ($val == false) {
    25.             INI::Set(static::$path, array($string => $string));
    26.             INI::Save();
    27.             return $string;
    28.         }
    29.         return $val;
    30.     }
    31. }
    32.  
    33. // Алиасы Langage::Get();
    34. function _r($string) { 
    35.     return Langage::Get($string); 
    36. } 
    37. function _e($string) { 
    38.     echo Langage::Get($string); 
    39. }
    Описание функций:
    • Langage::Load("Директория с языками") - Устанавливает язык и папку с языковыми пакетами. Следует вызывать в начале работы.[/*:m]
    • Langage::Get("Ключ") - Возвращает перевод, создаёт INI файл если его нет, добавляет строку в INI файл если её нет.[/*:m][/list:u]

      Пример работы:
      Код (PHP):
      1. <?php
      2.  
      3. include('langage.class.php');
      4.  
      5. Langage::Load('langs/');
      6. _e('Какой то текст');
      7. _e('Текст 2');
      8. _e('Мой текст');
      Что делает?
      • Создаст файл langs/ru.lang.ini или langs/en.lang.ini, в дальнейшем будет использовать их.[/*:m]
      • Добавит значения в .ini файл если их там нет.[/*:m]
      • Нам остаётся лишь подправить перевод в .ini файле.[/*:m][/list:u]

        Есть замечания по поводу этого класса?
     
  9. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    аргументируй
     
  10. geone

    geone Новичок

    С нами с:
    4 окт 2015
    Сообщения:
    139
    Симпатии:
    0
    • Лишние запросы
    • Сложность правки (Можно написать скрипт для редактирования или через PMA)
    • БД будет похожа на свалку
    Я не понимаю как в БД можно вообще пихать текст для менюшки или футера может ещё каких то кнопок, ещё с переводами на несколько языков, а если я захочу на 5-20 языков приложение перевести? В БД можно только хранить перевод контента - статей, документации, не больше.
     
  11. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    кеширование
    воу, нет. Если ты это называешь таким образом, то я тебя тогда попрошу вернуться к этому вопросу через годик практики и переосмыслить его. Ибо если ты пишешь некий самописный сайт который нуждается в i18n, то видимо это что-то серьёзное, и там вполне можно написать за день (на самом деле за полчаса) полноценный редактор.
    Не будт.

    в чем разница? о_О Запросы? Боишься запросов?
     
  12. geone

    geone Новичок

    С нами с:
    4 окт 2015
    Сообщения:
    139
    Симпатии:
    0
    Во всём лень виновата)))
    В любом случае надо будет как нибудь организовать
     
  13. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    А от этого не уйти всё равно.

    Короче, что там следующее? :)
     
  14. geone

    geone Новичок

    С нами с:
    4 окт 2015
    Сообщения:
    139
    Симпатии:
    0
    Класс роутера. Но не сегодня, может через недельку. Надо погуглить набраться ума, сделать ЧПУ.

    Ну вот сам код, думаю сразу его в помойку и всё по новой:
    Код (PHP):
    1. <?php
    2.  
    3. // Класс роутера
    4. Class Router {
    5.     
    6.     private $registry;
    7.  
    8.     function __construct($registry) {
    9.         $this->registry = $registry;
    10.     }
    11.     
    12.     private function error404(){
    13.         include(SITE_PATH . DS . 'application' . DS . 'controllers' . DS . '404.php');
    14.         $class = 'Controller_404';
    15.         $controller = new $class($this->registry);
    16.         $controller->index();
    17.     }
    18.     
    19.     private function GET($var){
    20.         $result = (empty($_GET[$var])) ? '' : $_GET[$var];
    21.         unset($_GET[$var]);
    22.         if (empty($result)) $result = 'Index';
    23.         return $result;
    24.     }
    25.     
    26.     function start(){
    27.         $controller = $this->GET('controller');
    28.         $action = $this->GET('action');
    29.         
    30.         // Подключаем файл контроллера, если он имеется
    31.         $controllerFile = SITE_PATH . DS . 'application' . DS . 'controllers' . DS . $controller . '.php';
    32.         if(file_exists($controllerFile)){
    33.             include($controllerFile);
    34.         } else {
    35.             $this->error404();
    36.             return;
    37.         }
    38.         
    39.         $class = 'Controller_' . $controller;
    40.         $controller = new $class($this->registry);
    41.         
    42.         // Если экшен не существует - 404
    43.         if (!is_callable(array($controller, $action))) {
    44.             $this->error404();
    45.             return;
    46.         }
    47.  
    48.         // Выполняем экшен
    49.         $controller->$action();
    50.     }
    51. }
    52.  
     
  15. geone

    geone Новичок

    С нами с:
    4 окт 2015
    Сообщения:
    139
    Симпатии:
    0
    Я тут подумал какая MVC будет без нормального регистра? Вот и решил переделать его убрал Эксепшены и добавил доступ как к обычному массиву.

    Вот результат:
    Код (PHP):
    1. <?php
    2. // Класс хранилища
    3. Class Registry Implements ArrayAccess {
    4.  
    5.     private $vars = array();
    6.     
    7.     // Запись данных
    8.     function set($key, $var) {
    9.         if (isset($this->vars[$key]) == true) {
    10.             return false;
    11.         }
    12.         $this->vars[$key] = $var;
    13.         return true;
    14.     }
    15.  
    16.     // Получение данных
    17.     function get($key) {
    18.         if (isset($this->vars[$key]) == false) {
    19.             return null;
    20.         }
    21.         return $this->vars[$key];
    22.     }
    23.  
    24.     // Удаление данных
    25.     function remove($var) {
    26.         unset($this->vars[$key]);
    27.     }
    28.     
    29.     // Для обращения к обьекту как к массиву
    30.     function offsetExists($offset) {
    31.         return isset($this->vars[$offset]);
    32.     }
    33.     function offsetGet($offset) {
    34.         return $this->get($offset);
    35.     }
    36.     function offsetSet($offset, $value) {
    37.         $this->set($offset, $value);
    38.     }
    39.     function offsetUnset($offset) {
    40.         unset($this->vars[$offset]);
    41.     }
    42. }
     
  16. geone

    geone Новичок

    С нами с:
    4 окт 2015
    Сообщения:
    139
    Симпатии:
    0
    Может регист статиком сделать? Что бы не получилось много экземпляров класса.
     
  17. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.902
    Симпатии:
    969
    мож для начала перезапись разрешить?
     
  18. geone

    geone Новичок

    С нами с:
    4 окт 2015
    Сообщения:
    139
    Симпатии:
    0
    Это можно.
     
  19. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.555
    Симпатии:
    1.754
    Сделайте синглтоном.
     
  20. geone

    geone Новичок

    С нами с:
    4 окт 2015
    Сообщения:
    139
    Симпатии:
    0
    А какие с ним проблемы могут возникнуть?
     
  21. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    проблемы? с синглтоном? синглтон это синглтон, он не имеет проблем как таковой.
     
  22. geone

    geone Новичок

    С нами с:
    4 окт 2015
    Сообщения:
    139
    Симпатии:
    0
    Я просто только сегодня узнал что это такое. В блогах пишут что это прохо, я им не верю)))

    Вот в общем что получилось:
    Код (PHP):
    1. <?php
    2. // Класс хранилища
    3. Class Registry Implements ArrayAccess {
    4.     
    5.     protected static $_instance; // Здесь экземпляр класса
    6.     private $vars = array(); // Само хранилище
    7.     
    8.     private function __construct(){}
    9.     private function __clone(){}
    10.     
    11.     public static function GetInstance() {
    12.         // Проверяем актуальность экземпляра
    13.         if (null === self::$_instance) {
    14.             // Создаем новый экземпляр
    15.             self::$_instance = new self();
    16.         }
    17.         // Возвращаем созданный или существующий экземпляр
    18.         return self::$_instance;
    19.     }
    20.         
    21.     // Запись данных
    22.     function Set($key, $var) {
    23.         $this->vars[$key] = $var;
    24.         return true;
    25.     }
    26.  
    27.     // Получение данных
    28.     function Get($key) {
    29.         if (isset($this->vars[$key]) == false) {
    30.             return null;
    31.         }
    32.         return $this->vars[$key];
    33.     }
    34.  
    35.     // Удаление данных
    36.     function Remove($var) {
    37.         unset($this->vars[$key]);
    38.     }
    39.     
    40.     // Для обращения к обьекту как к массиву
    41.     function offsetExists($offset) {
    42.         return isset($this->vars[$offset]);
    43.     }
    44.     function offsetGet($offset) {
    45.         return $this->get($offset);
    46.     }
    47.     function offsetSet($offset, $value) {
    48.         $this->set($offset, $value);
    49.     }
    50.     function offsetUnset($offset) {
    51.         unset($this->vars[$offset]);
    52.     }
    53. }
     
  23. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    в смысле "плохо"?

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

    И кстати не обязательно возвращать этот экземпляр. Если методов мало и они заранее известны и не будут меняться, то опять же можно обернуть методы объекта в статик методы для удобства.
     
  24. geone

    geone Новичок

    С нами с:
    4 окт 2015
    Сообщения:
    139
    Симпатии:
    0
    Я об этом уже думал. Но регист это безопасная замена глобальным переменным, и мне хочется чтобы с ним можно было обращаться как с обычной переменной. Разве ArrayAccess будет работать в статистическом классе?
     
  25. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    при чем тут глобальные переменные? о_О