LINUX.ORG.RU

file_put_contents ведет себя крайне странно...

 ,


0

1

Кароч file_put_contents сохраняет не все содержимое строковой переменной. Причем там две переменные сохраняются в два файла - в первом случае все сохранено целиком, во втором обрыв - урезается до 4096 байт. Бывает какое-то ограничение на длину? Есть простой способ обойти не сохраняя в несколько приемов строку?

Но это только если повезет. На большинстве хитов просто создается пустой файл.

Чего за хрень?

★★★★★

Последнее исправление: Suntechnic (всего исправлений: 2)

Ну почему обрывает запись это разобрался - apc.user_entries_hint.

Вообще классная настройка, жалко что человек который это придумал наверняка живет далеко...

Но вот почему следующий за только что созданным файл в 8Кб, файл в одну строку создается пустым, совершенно неясно.

Suntechnic ★★★★★
() автор топика
Последнее исправление: Suntechnic (всего исправлений: 1)
Ответ на: комментарий от Suntechnic

Вообще все страньшее и страньшее...

Сохраняю одну и ту же строку в два файла друг за другом, а потом пишу коротенькую строчку в третий. Перед этим сделав ini_set('apc.user_entries_hint', 32768); - иногда оба создаются нормально, а третий пустой. Иногда все три пустые. Пару раз первый создается нормально, второй обрезан до 4096Б, третий пустой.

php берет некоторый параметры из /dev/random ?

Suntechnic ★★★★★
() автор топика
Ответ на: комментарий от Suntechnic

APC — бяка. Несколько лет уже избегаю его использовать. И много граблей таким способом обошёл.

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

Да, но на некоторый сайтах оно стоит и повлиять я не могу на это...

Какой сцука урод это придумал? Сохраняю файл теперь так:

$loaderScript = getLoader($loadMethod);
    $arLS = explode("\n", $loaderScript);
    $saveLoaderResult = 0;
    foreach ($arLS as $strLS) {
        $saveLoaderResult = $saveLoaderResult + file_put_contents($srDir.'/loader.php', $strLS."\n", FILE_APPEND);
    }

Ну не дикость ли?

Причем что еще интересно - короче оно перестает писать во все последующие файлы если размер записываемых данных в одном из вызовов превысил apc.user_entries_hint.

Т.е. в цикле по строке я могу хоть весь интернет сохранять, а если за один раз - обломайтесь, причем не только в месте ошибки, но и во всех последующих. Как это можно применять в продакшене я просто не представляю. Нужно быть упоротым на всю голову...

Suntechnic ★★★★★
() автор топика

похоже на нехватку памяти - проверить memory_get_peak_usage и разрешенный объем в ini на выхлопе shutdown и смотреть логи сервера

swwwfactory ★★
()
Ответ на: комментарий от swwwfactory

А при чем тут нехватка памяти?

Ну вот смотри, я ту же восьмикилобайтную строку разбиваю в массив по символу «\n» и из массива записываю построчно - все отлично. Пытаюсь записать целиком - обламываюсь. Кстати очевидно, что строка + она же разобранная в массив > чем просто строка. Да и это происходит в начале хита - дальше память будет отлетать сотнями и работает.

Suntechnic ★★★★★
() автор топика
Ответ на: комментарий от Suntechnic

А при чем тут нехватка памяти?

не утверждаю - просто констатирую, что выглядит похоже.

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

В коде, (не мешало бы покрасившее оформить) $srDir не объявляется: это мелочь, но лучше явно объявить.

swwwfactory ★★
()
Ответ на: комментарий от Suntechnic
; The number of seconds a cache entry is allowed to idle in a slot in case this
; cache entry slot is needed by another entry.
apc.ttl=0

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

hidden_4003
()
Ответ на: комментарий от swwwfactory

Ну это же не весь код ;)

Просто кусок скопипастил. Все там объявляется. Но там вообще заморока. Куча подгрузок и eval'ов. Это обнавлялка короч - она в CMS'ке должна запустится, скачать код апдейтера, запустить его, он должен удалить инклюд модуля, скачать новый код модуля, сохранить его, выполнить, убедится что тот работает нормально, добавить инклюд. Т.е. там все не так просто...

Suntechnic ★★★★★
() автор топика
Ответ на: комментарий от hidden_4003

Ага - спасибо. Гляну. Мне вообще не понятно какого хрена настройки кэширования, должны влиять на сохраняемые данные. Ну пишет у меня оно в файл. Кто, мать твою, сказал тебе что это кэш?! - вот такой у меня вопрос к apc.

Suntechnic ★★★★★
() автор топика
Ответ на: комментарий от Suntechnic

Ну это же не весь код ;)

Просто кусок скопипастил.

и тем не менее - pretty print не помешает

А как ведет себя, если отключить APC?

вообще в настоящий момент работать с ним не рекомендуется - есть штатный кэшер в свежих версиях php

swwwfactory ★★
()
Ответ на: комментарий от Suntechnic

он должен удалить инклюд модуля,

вот так делать - точно можно нарваться на глюки...

Это не эрланг - а одноразовый ППШ,там нет подгрузки и замены кода.

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

swwwfactory ★★
()
Последнее исправление: swwwfactory (всего исправлений: 1)
Ответ на: комментарий от swwwfactory

А я не пытаюсь переопределить загруженный код. Там самый обычный инклюд в два этапа инклюдится файл который инклюдит другой файл. Вот этот файл с инклюдами и удаляется. Т.е. речь не идет о том, чтобы отменить уже инклюженный код. Речь о том, чтобы снести файл который должен его инклюдить. Заменить код, проверить работоспособность, вернуть файл с инклюдом на место. Ну обновлялка модуля короче. Причем модуль не от продакшена - это дебагер мой, так что в нем никакой критичности.

Suntechnic ★★★★★
() автор топика
Ответ на: комментарий от Suntechnic

ok - тогда APC отключить и посмотреть как без него.

autoload там нельзя использовать? Инклюды - это ад, лучше через spl_autoload. Код модулей завернуть в классы и вызывать код только через классы. Автозагрузчик умеет по цепочке работать. В идеале в проекте нигде не должно быть инклюдов, кроме как на загрузку классов и некоторых критически важных.

Если сильно хочется, то так можно еще:

где-то записываешь файл '/path/to/fname.php' примерно такого вида:

<?php
return
  function($arg1) {
    //your code here
    return $arg1 . ' world';
  };


потом инклюдишь так:

$ret = (include '/path/to/fname.php' );
echo call_user_func($ret, 'hello');

swwwfactory ★★
()
Последнее исправление: swwwfactory (всего исправлений: 1)
Ответ на: комментарий от swwwfactory

Инклюды - это ад

Ад адом не испортишь. И кстати именно для разбирательства, в том числе, и с этим адом этот дебаггер и запилен. Проект вообще не мой - мой только этот модуль и он нужен только чтобы разбираться с этим проектом. Но так как сайтов на этой CMS у меня over20 обновлять на каждом рукам дебагер при добавление функционала в него лень. Вот и пилю обновлялку. Кстати это еще я не все расказал - на самом деле реальность куда хуже. Ну в частности обновляется так у меня не сам дебагер, а его загрузчик, а дебагер КАЖДЫЙ раз инклюдится с удаленного сервера, прикинь.

где-то записываешь файл '/path/to/fname.php' примерно такого вида...

И чо, это работает? Прикольный трюк - может и пригодится. Спасибо.

Suntechnic ★★★★★
() автор топика
Последнее исправление: Suntechnic (всего исправлений: 1)
Ответ на: комментарий от Suntechnic

И кстати именно для разбирательства

мне вполне хватает связки xdebug+cache grind - отличный набор + плагины и может трассу расхода памяти выдать

Вот и пилю обновлялку.

почитай про эрланг в этом ключе

И чо, это работает? Прикольный трюк - может и пригодится. Спасибо.

это работает для 5.3+

swwwfactory ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.