Вопросы при работе с локальными файлами

Etarus

Новичок
С РНР я знаком относительно недавно, знаю язык поверхностно, но изучаю по мере возможности.
В принципе как это все работает - понятно. Но дьявол в деталях... и подобных каверзных вопросов вполне много.
Но перейдем к конкретному вопросу. Точнее вопросам.
Каково время жизни статического параметра класса? Предполагаю, что пока идет сессия.
Тестируя скорость работы заметил, что функции file_exists() и fopen() крайне времязатратные, но без них никуда. Попробовал разные варианты, в итоге пришел к такому варианту.
PHP:
<?php

class Logger
{
    public static $handle;
    public static $home = "C:";

    public static function open()
    {
        $year = date("Y");
        $month = date("m");
        $day = date("d");

        $path = self::$home . "\\$year\\$month";

        if (!file_exists($path))
            mkdir($path, 0777, true);

        $fileName = "$year-$month-$day.log";

        if (empty(self::$handle)) {

            $fullPath = "$path\\$fileName";
            self::$handle = fopen($fullPath, "ab");

        }else {

            $meta_data = stream_get_meta_data(self::$handle);
            $streamFileUri = explode("\\", $meta_data["uri"]);
            $index = count($streamFileUri) - 1;
            $streamFileName = $streamFileUri[$index];

            if ($streamFileName != $fileName) {

                $fullPath = "$path\\$streamFileName";
                self::$handle = fopen($fullPath, "ab");
            }
        }
    }

    public static function write($message, $type = "INFO")
    {
        self::open();
        $time = date("H:i:s");
        fwrite(self::$handle, "$time\t$type\t$message" . PHP_EOL);
        fflush(self::$handle);
    }

    public static function setHome($home)
    {
        self::$home = $home;
    }
}
150 000 записей у меня записались в файл за 14 секунд.

Если открывать и закрывать файл после каждой записи - время вырастит в 10 раз.
Что крайне медленно. Но безопасен ли мой способ? Не будет ли ошибок доступа к файлу при попытке параллельной записи разными пользователями?
Насколько корректен в принципе мой способ? Может я чего-то не учел по-незнанию, или оно в принципе работает только пока у сайта 1 пользователь?

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

AnrDaemon

Продвинутый новичок
1. Используй "/" как разделитель пути.
2. Не надо никаких 777 и прочей чехни в mkdir(). Сам себе яму роешь ведь.
3. Да, представь себе, не надо постоянно открывать-закрывать файл. Чтобы отдать буфера PHP системе, есть fflush().
 

Etarus

Новичок
1. Используй "/" как разделитель пути.
2. Не надо никаких 777 и прочей чехни в mkdir(). Сам себе яму роешь ведь.
3. Да, представь себе, не надо постоянно открывать-закрывать файл. Чтобы отдать буфера PHP системе, есть fflush().
1. Спасибо, заменю.
2. А как тогда проверить есть ли данные папки? mkdir умеет создавать их рекурсивно, чем я и воспользовался.
3. Это понятно, но как его правильно сохранить, и главное - вовремя изменить на новый файл? Ведь задумка в том, что на каждые сутки отдельный файл-лог.
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
@AnrDaemon, В PHP есть переменная DIRECTORY_SEPARATOR как раз для таких как ТС.

@Etarus, Для записи логов люди придумали Monolog, посмотри в нутро.
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
@Вурдалак, надеяться на поддержку имхо не очень правильно, я предпочел просто на конкретной платформе взять именно нужный разделитель, так доходчивей?
 

AmdY

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

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
@AmdY, ну мне пофигу, я просто не замечаю длины, а часто просто делаю подконстанту DS

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

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
@fixxxer, SoF?) Недавно там встречал тред про разделители путей.

PS: Ну, я просто очень, ОЧЕНЬ, люблю чтобы все было прям вот правильно. Хоть и не хватает знаний, чтобы спорить о DI/IOC, как тут у нас любят, но пофик)
 

fixxxer

К.О.
Партнер клуба
@c0dex, это строчка из кода в первом сообщении ТС-а.

В целом, на винде можно безопасно использовать "/" в качестве разделителя, все виндовые api-функции это прекрасно понимают (даже DOS-овские int21h понимали, и даже когда-то в DOS была настройка соответствующая). А вот когда _парсишь_ виндовый путь, тут уже без DIRECTORY_SEPARATOR не обойтись (хотя в 95% случаев достаточно встроенных в php функций типа dirname / basename).
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
@fixxxer, да я понимаю, но я в свою очередь обосновал свое замечание именно универсальностью подхода, не зависимо от того, какие функции и что вернут, чтобы везде был подходящий разделитель.
 
Сверху