Laravelde çoğumuzun dikkat etmediyi bir problemin basit ve etkili çözümünü sizinle paylaşmak istiyorum.
Projelerde rahat ve düzenli kod için modelleri direkt cache yazıyoruz cache den geri alırken kullanım da kolay oluyor.
$categories = \Cache::rememberForever(Category::class, function () {
return Category::all();
});
benim örneğimde 3400 category var redisde tutduğu yer 5.2mb. ram sıkıntımız olmazsa bile bu boyutda datanın php işlenmesi belirli bir süre alıyor yazarken ve okurken. göstereceğim çözümle bunu 2.6mb düşürücez. öncelikle bunun sebebini açıklayım laravel php nin serialize fonksiyonu kullanıyor bu fonksiyon obje içindeki propertylerin hepsini alıyor. model içinde hiç değişmeyen bir sürü property var
($table,$hidden,$visible,$fillable) bunlar her model için tekrar tekrar serialize oluyor.neyse ki php nin buna bir çözümü var Serializable bu interface kullanarak serialize ve unserialize işlemini dilediğimiz gibi yönete biliriz.
class Category extends Model implements \Serializable
{
public function serialize()
{
if (method_exists($this, '__sleep')) {
$this->__sleep(); //laravel 7
}
$serialized = [];
foreach ($this->serializable() as $property) {
$serialized[$property] = $this->{$property};
}
return \serialize($serialized);
}
public function unserialize($serialized)
{
$serialized = \unserialize($serialized);
foreach ($serialized as $property => $value) {
$this->{$property} = $value;
}
$this->__wakeup();
}
protected function serializable(): array
{
return [
'exists',
'original',
'attributes',
'relations',
];
}
}
kullanacaksanız tüm cacheleri mutlaka silin çünki Serializable sadece kendisi ile uyumlu çalışıyor
mövcut yapı bozulmadan daha basit şekilde __sleep method kullanıla bilinir sebebini bilmesemde unserialize işlemi sırasında \Serializable interface kullanmak daha hızlı oluyor benim örneğimde 4ms fark .
class Category extends Model
{
public function __sleep()
{
if (is_callable('parent::__sleep')) {
parent::__sleep(); //laravel 7
}
return $this->serializable();
}
protected function serializable(): array
{
return [
'exists',
'original',
'attributes',
'relations',
];
}
}
php 7.4 sonrası kullandığımız interface ihtiyac yok __serialize() and __unserialize()
Edit: modelin boot ve castla ilgili sorunlar __sleep ____wakeup methodları ile düzeltildi