Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
Всем привет.
Немного погуглил, но решения пока не увидел, возможно плохо искал.
5 дней как изучаю (заодно и небольшую работу делаю) laravel и вот дошел до кэша.
Суть вопроса в организации кэша и зависимости.
К примеру возьмём файловый кэш, по дефолу всё летит в папку path('storage').'cache' , как для примера я организую каталог:
->0
->-> 0:1
->->->0:1:1
->->->0:1:2
->-> 0:2
->->->0:2:1
->->->0:2:2
->->->0:2:3
и.т.д
Всё бросать в одну папку, как-то не кэшерно, да и при большом количестве файлов в одной директории будут тормоза при работе с кэшем, плюс к примеру я добавил уровень 0:1:1. убил кэш 0:1:1, 0:1 и 0.
Вопрос в том, что я не нашол как этим всем управлять, единственное что пришло с лёту, это создать свой класс и типа переопределять настройки в зависимости от переданных данных, как пример
MyCache::cache_put($key, $value, $lifetime = 0, array('driver'=>'file','opt_cache_key'=>'dir/direct/directory'));
И уже в своём классе разруливать всё. т.е. в данном примере переопределять $path и $driver.
Практически всё получается, но чувствую, что я чего-то не то наворотил и есть более изящные методы на которые я ещё не нашел ответ.
Прошу помощи профи, куда рыть?
If you think it’s expensive to hire a professional to do the job, wait until you hire an amateur.
Не в сети
- Вопрос в том, что я не нашол как этим всем управлять
Этим и нельзя управлять. Стандартный кэш в Laravel обеспечивается драйверами — кроме файлового там есть СУБД и NoSQL (Redis/Memcached). У них плоская структура, видимо поэтому и файловый кэш сделали плоским.
Единственный (и вполне хороший) вариант — написать свой драйвер, не обязательно его даже наследовать от стандартного файлового драйвера, кода там очень мало.
- opt_cache_key
Я не думаю, что стоит вручную передавать путь, куда нужно сохранить файл — проще сделать это автоматически:
$dir = substr(md5($key), 0, 2)
Таким образом папка кэша будет содержать максимум 256 подпапок; на 1 млн. записей это меньше 20 000 файлов, что для современных ФС не очень большая проблема.
Не в сети
Спасибо за ответ Proger_XP,
...кроме файлового там есть СУБД и NoSQL (Redis/Memcached). У них плоская структура, видимо поэтому и файловый кэш сделали плоским.
Это не причина, так как зависимость всё равно строится по ключу названия (которое можно шифровать как для примера) и по ключу самого кэша, которое имет вид /folder/subfolder/.
Теперь, если это файловый кэшь, то с ключа кэша строиться структура папок, если это к примеру APC, то ключь кэша будет добавляться в начало ключа названия кэша.
И теперь только логика будет спасать нас.
Я не думаю, что стоит вручную передавать путь, куда нужно сохранить файл — проще сделать это автоматически:
$dir = substr(md5($key), 0, 2)
Всё в ручную тоже не сделаешь, ну и на автомате тоже не всё можно решить.
В вашем случае, или нужно будут рубить весь кэшь при маленьком пуке, или я не врубился значит.
Как для примера: файловый кэш:
->folder
->->subfolder
>->->$id
->->->->key
APC кэш:
/folder/subfolder/$id/key
key - ключь название, можео просто id, можно с префиксами или органиации своей логики, blog-md5($id_comment).
Теперь к примеру мы легко можем убить весь кэш который находиться по ключу кэша folder/subfolder/ или folder/ и.т.д, так-же и в APC (плоском кэше). Т.е. можно строить зависимости кэша и связи.
С ответа понял, что здесь пляшет каждый как хочет И в Laravel нету Using groups для этих целей, как для примера.
Тогда встречный вопрос, как вы бы изменяли $path файлового кжша?, ведь каждый раз делать подобное
if(self::$cachekey != '')
{
Cache::extend('new', function()
{
$kk = 'cache/'.ECache::$cachekey;
return new Laravel\Cache\Drivers\File(path('storage').$kk.DS);
});
}
Cache::driver('new')->put($key, $value, $minutes);
не правильно, или как?
Изменено Artdevue (17.04.2013 22:08:35)
If you think it’s expensive to hire a professional to do the job, wait until you hire an amateur.
Не в сети
- Это не причина, так как зависимость всё равно строится по ключу названия
Я просто предположил, какая могла быть причина в уме Тейлора, когда он писал файловый драйвер. Мне это решение тоже не кажется оптимальным, но плоскую структуру проще поддерживать хотя бы потому, что не нужно думать о вложенных папках.
- Теперь к примеру мы легко можем убить весь кэш который находиться по ключу кэша folder/subfolder/ или folder/ и.т.д
Согласен, это решение лучше всего.
- Тогда встречный вопрос, как вы бы изменяли $path файлового кжша?
Никак, придётся вставлять вызовы для его изменения перед чтением/записью и восстанавливать значения после. Я бы написал свой отдельный класс, так как в стандартном драйвере возможность группировки не предусмотрена и вряд ли получится элегантно его добавить — да и зачем, ведь её будет поддерживать только твой собственный драйвер.
Не в сети
Спасибо, так и сделал, просто скопировал стандартный драйвер фаловый, переименовал, добавил свои хотелки, зарегистрировал и по дефолу его установил в настройках. Теперь если даже буду использовать ключь /папка/подпапка/ключ, то при использовании APC к примеру у меня сохраняет с названием /папка/подпапка/ключ , а при файловом кэше, просто разбиваю на массив строку по слешу "/" и сохраняю по папкам и название.
Кстати, в стандартном драйвере слеш в названии не прокатывает именно для файлового драйвера.
В общем пока удолетворён, а то немного растроелся изначально.
Ещё раз спасибо за ваши ответы.
If you think it’s expensive to hire a professional to do the job, wait until you hire an amateur.
Не в сети
Раз начал эту тему, то выкладываю исходник, может кому пригодиться
https://gist.github.com/artdevue/5424557
Можно установить по дефолу или вызывать через драйвер.
Что изменилось из стандартного драйвера? - работа с директориями.
Всё просто, в названии ключа, если указываете слешь, то кэшь будет записанн по папкам.
К примеру:
Cache::put('testik1/testik2/test3', 'Это тестовый кэш 2', 0);
сохранит файл с название test3.php в папке кэша и директории path('storage').'cache/testik1/testik2/' .
0 - время пожизненное (это из изменений)
Сразу вопрос возникнет. а почему я храню с разрешение .php? Ну. вопервых я не использую serialize, так как на больших файлах это забирает время, возможно для кого-то это не важный параметр, но была такая прихоть.
При сохранении кэша вышеуказанным способом, файл кэша примерно выглядет так
<?php return 'Это тестовый кэш 2';
если мы укажем время 60 минут к примеру, то так
<?php if(time() > 1366428043){return null;} return 'Это тестовый кэш 2';
Думаю здесь объяснять не нужно.
Остальное всё стандартное. единственное добавлась рекурсивное удаление не полностью кэша, а указанного каталога
Cache::flush('testik1/testik2');
Удалит все файлы и вложенные папки в директории path('storage').'cache/testik1/testik2/'.
If you think it’s expensive to hire a professional to do the job, wait until you hire an amateur.
Не в сети
Если интересно ниже кое-какие замечания.
PHPpublic function geFile($key)
Похоже на опечатку. Немного странно видеть смешение camelCase с c_style тут и ниже.
PHPflock()
Не уверен, насколько такой механизм блокировки работает — по-моему LOCK_EX, который используется у file_put_contents() ниже, не связан с пользовательскими flock(), во всяком случае это не переносимое поведение.
PHPreturn (object) array('fileName'=>$fileName, 'fileDir'=>$fileDir);
Можно заменить на PHPcompact('fileName', 'fileDir')
.
PHP$expireContent= 'if(time() > ' . $expirationTS . '){return null;}';
Интересное решение, но оно затруднит обновление времени кеша («touch»).
- Остальное всё стандартное. единственное добавлась рекурсивное удаление не полностью кэша, а указанного каталога
Из-за использования PHPglob('*')
файлы (ключи), начинающиеся с точки, удалены не будут.
Не в сети
Спасибо Proger_XP за замечания.
If you think it’s expensive to hire a professional to do the job, wait until you hire an amateur.
Не в сети