Накладные расходы на открытие дескриптора файла в PHP? - PullRequest
1 голос
/ 23 октября 2009

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

// Open, Write, Close; Open, Write, Close...
function write($message) {
    $fh = fopen('file.log', 'a');
    fwrite($fh, $message . "\n");
    fclose($fh);
}

// OR -----

// Open, Write, Write, Write..., Close
function __construct() {
    $this->fh = fopen('file.log', 'a');
}
function __destruct() {
    fclose($this->fh);
}
function write($message) {
    fwrite($fh, $message . "\n");
}

Я предполагаю, что этот класс будет загружаться и создаваться на каждой странице, но не обязательно использоваться, хотя, скорее всего, это будет.

Существуют ли какие-либо ошибки, связанные с производительностью, безопасностью или другими недостатками, и что бы вы порекомендовали?

Ответы [ 4 ]

2 голосов
/ 23 октября 2009

Я не могу дать вам номер, но открытие файла только для его повторного открытия и повторного открытия обойдется вам в что-то. И я говорю на уровне ОС, а не только PHP. Вызов в ядро ​​для open() (или CreateFile(), если вы говорите в Windows), сопоставление строк пути с сущностями из вашей файловой системы, чтение структуры каталогов с диска, затем еще один системный вызов для закрытия дескриптора ... Особенно, если у вас большой Я бы не стал делать все это слишком много. Или проведите несколько измерений, чтобы проверить, все ли в порядке.

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

1 голос
/ 23 октября 2009

Второй метод явно лучше, ИМО. Открытие и закрытие дескриптора файла имеет свою стоимость, и, хотя оно относительно незначительно, оно довольно много, если вы делаете это много в приложении (хотя, если это очень редко, это не будет иметь значения Я не думаю). И если вам когда-нибудь понадобится добавить некоторые дополнительные функции настройки или очистки, второй метод будет наиболее чистым, поскольку вы просто добавляете некоторый код в метод __construct / __destruct.

1 голос
/ 23 октября 2009

Вот альтернативная версия:

function log($message) {
  global $_log;
  if (!defined(LOG_OPEN)) {
    define(LOG_OPEN, true);
    $_log = fopen('filename.log', 'w');
    register_shutdown_function('close_log');
  }
  fwrite($_log, $message . "\n");
}

function close_log() {
  global $_log;
  fclose($_log);
}

По крайней мере, тогда вы открываете журнал только тогда, когда пишете сообщение.

Это будет вам чего-то стоить. В великой схеме сетевых задержек и т. Д. Я сомневаюсь, что это будет важно, если вы не начнете открывать много файлов. Я сомневаюсь, что этот журнал даже измерим по своему эффекту.

1 голос
/ 23 октября 2009

Зависит от того, что вы регистрируете.

Действительно, вторая версия лучше. Думайте об этом так:

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

Надеюсь, это прояснит для вас.

При желании вы можете передать указатель файла на первый метод и только метод должен выполнить запись.

...