Я давно не программировал на PHP, но этот вопрос сегодня заинтересовал меня. : D
Предложение
Как мне решить эту проблему?
Сгенерировать ли я новый файл с новым именем в том же каталоге и отменить связь старого файла в цикле for?
Просто используйте 3 amigos fopen()
, fwrite()
& fclose()
снова, поскольку fwrite
также перезапишет все содержимое существующего файла.
if (file_exists($new_filename)) {
if (is_writable($new_filename)) {
$fh = fopen($new_filename,'wb');
fwrite($fh, $md_file_content);
fclose($fh);
if (EQ::isLocalServer()) {
echo $equity_symbol . " ? " . ConfigConstants::NEW_LINE;
}
} else {
if (EQ::isLocalServer()) {
echo $equity_symbol . " symbol MD file is not writable in " . __METHOD__ . " ? Maybe, check permissions!" . ConfigConstants::NEW_LINE;
}
}
} else {
$fh = fopen($new_filename, 'wb');
fwrite($fh, $md_file_content);
fclose($fh);
if (EQ::isLocalServer()) {
echo $equity_symbol . " front md file does not exit in " . __METHOD__ . " It's writing on the database now ?" . ConfigConstants::NEW_LINE;
}
}
Ради СУХОГО принципа:
// It's smart to put the logging and similar tasks in a separate function,
// after you end up writing the same thing over and over again.
public static function log($content)
{
if (EQ::isLocalServer()) {
echo $content;
}
}
public static function writeFinalStringOnDatabase($equity_symbol, $md_file_content, $no_extension_filename)
{
$md_file_content = $md_file_content . ConfigConstants::NEW_LINE . ConfigConstants::NEW_LINE;
$dir = __DIR__ . ConfigConstants::DIR_FRONT_SYMBOLS_MD_FILES; // symbols front directory
$new_filename = EQ::generateFileNameFromLeadingURL($no_extension_filename, $dir);
$file_already_exists = file_exists($new_filename);
if ($file_already_exists && !is_writable($new_filename)) {
EQ::log($equity_symbol . " symbol MD file is not writable in " . __METHOD__ . " ? Maybe, check permissions!" . ConfigConstants::NEW_LINE);
} else {
$fh = fopen($new_filename,'wb'); // you should also check whether fopen succeeded
fwrite($fh, $md_file_content); // you should also check whether fwrite succeeded
if ($file_already_exists) {
EQ::log($equity_symbol . " ? " . ConfigConstants::NEW_LINE);
} else {
EQ::log($equity_symbol . " front md file does not exit in " . __METHOD__ . " It's writing on the database now ?" . ConfigConstants::NEW_LINE);
}
fclose($fh);
}
}
Возможная причина
tl; dr Слишком много накладных расходов из-за используемого API строки Zend .
Официальное Руководство по PHP гласит:
file_put_contents()
идентичен вызову fopen()
, fwrite()
и fclose()
для последовательной записи данных в файл.
Однако, если вы посмотрите на исходный код PHP на GitHub , вы увидите, что часть "запись данных" немного отличается в file_put_contents()
и fwrite()
.
ret = php_stream_write(stream, input, num_bytes);
numbytes = php_stream_write(stream, Z_STRVAL_P(data), Z_STRLEN_P(data));
(макросы Z_STR....
определены здесь , если вам интересно).
Итак, я подозреваю, что, возможно, Zend string API вызывает издержки при использовании file_put_contents
.
примечание
Сначала я подумал, что каждый вызов file_put_contents()
создает новый контекст потока, так как строки, связанные с созданием контекста, также немного отличались:
PHP_NAMED_FUNCTION(php_if_fopen)
( Ссылка ):
context = php_stream_context_from_zval(zcontext, 0);
PHP_FUNCTION(file_put_contents)
( Ссылка ):
context = php_stream_context_from_zval(zcontext, flags & PHP_FILE_NO_DEFAULT_CONTEXT);
Однако, при ближайшем рассмотрении, php_stream_context_from_zval выполняется эффективно с теми же параметрами, то есть первый параметр zcontext
равен null
, и так как вы не передаете flags
file_put_contents
, flags & PHP_FILE_NO_DEFAULT_CONTEXT
становится также 0
и передается как второй параметр.
Итак, я предполагаю, что контекст потока по умолчанию повторно используется здесь при каждом вызове. Поскольку это, по-видимому, поток типа persistent
, он не удаляется после вызова php_stream_close () .
Таким образом, Fazit , как говорят немцы, заключается в том, что в обоих случаях очевидно, что нет никаких дополнительных издержек или одинаково одинаковых накладных расходов на создание или повторное использование потока.
Спасибо за чтение.