4.3. الـ frontends المتوفرة فى Zend_Cache

4.3.1. Zend_Cache_Core

4.3.1.1. مقدمة

Zend_Cache_Core هو frontend مميز لأنه جوهر الـ module . هو عبارة cache frontend عام و هناك classes أخرى ممتدة منه.

[ملاحظة] ملاحظة

كل الـ frontends ترث من Zend_Cache_Core و بهذا كل الـ methods و الـ options الخاصة به (سيتم توضيحها لاحقاً) متوفرة فى الـ frontends الأخرى , لذلك لن نقوم بشرحها هناك.

4.3.1.2. الـ options المتوفرة

هذه الـ options يتم تمريرها الى الـ factory method كما كان موضحاً فى امثلة سابقة.

جدول 4.1. الـ options المتوفرة لـ Zend_Cache_Core

الـ Option الـ Data Type الـ Default Value الوصف
caching boolean true تقوم بإقاف او تشغيل عملية الـ caching ( من الممكن ان تكن مفيدة عند عمل debuging للكود الواقع فى نطاق عمل عملية الـ caching ).
lifeTime int 3600 فترة صلاحية الـ cache record (بالثوانى), إن كانت قيمتها تساوى null فسيكون الـ cache record صالح للإستخدام دائما.
logging boolean false إن كانت قيمتها تساوى TRUE, سيتم تنشيط عملية الـ loging من خلال Zend_Log . (لكن سيبطئ من عمل النظام نسبياً)
writeControl boolean true تقوم بايقاف او تشغيل الـ write control (أى سيتم قرائة الـ cache بعد حفظه للتأكد من عدم وجود اخطاء به). تشغيل الـ write control سيتسبب فى ابطاء عملية كتابة "حفظ" الـ cache قليلا, لكنه لن يؤثر فى علية القرائة. (يمكن ان بساعد فى اكتشاف ملفات الـ cache المعطوبة "الفاسدة" و لكنه برغم ذالك لا يعتبر control ممتاز )
automaticSerialization boolean false تقوم بتشغيل او ايقاف عملية الـ serialization التلقائية , يمكن ان يتم استخدامها عند الحاجة لحفظ بيانات مباشرة , حيث ان هذه البيانات ليست من النوع string. (لكنها ابطء)
automaticCleaningFactor int 10 تقوم بتشغيل او ايقاف عملية التنظيف (garbage collector): القيمة 0 تعنى إيقاف عملية التنظيف التلقائى للـ cache , القيمة 1 تعنى تشغيل عملية التنظيف بشكل منتظم, و عندما تكن القيمة هى x > 1 سيتم تنفيذ عملية تنظيف تلقائى عشوائية لكل عدد x من عمليات الكتابة.

4.3.1.3. امثلة

تم اعطاء مثال فى بداية هذا الفصل.

إن كنت تقم بحفظ بيانات من النوع string فقط فى الـ cache (من الممكن حفظ بيانات من النوع bool ايضا بتشغيل الـ option المسمى "automaticSerialization" ) , يمكنك ان تستخدم بنية كود ادق مثل هذه :

<?php  
             
// we assume you already have $cache

$id = 'myBigLoop'; // cache id of "what we want to cache"

if (!($data = $cache->load($id))) {
    // cache miss
    
    $data = '';
    for ($i = 0; $i < 10000; $i++) {
        $data = $data . $i;
    }
    
    $cache->save($data);
    
} 

// [...] do something with $data (echo it, pass it on etc.)
             
?>       

إن كنت تريد حفظ اكثر من بلوك او مجموعة بيانات مختلفة, فهى نفس الفكرة :

<?php  
             
// make sure you use unique identifiers:
$id1 = 'foo';
$id2 = 'bar';

// block 1
if (!($data = $cache->load($id1))) {
    // cache missed
    
    $data = '';
    for ($i=0;$i<10000;$i++) {
        $data = $data . $i;
    }
    
    $cache->save($data);
    
} 
echo($data);

// this isn't affected by caching
echo('NEVER CACHED! ');

// block 2
if (!($data = $cache->load($id2))) {
    // cache missed
    
    $data = '';
    for ($i=0;$i<10000;$i++) {
        $data = $data . '!';
    }
    
    $cache->save($data);
    
} 
echo($data);

?>       

4.3.2. Zend_Cache_Frontend_Output

4.3.2.1. مقدمة

Zend_Cache_Frontend_Output هو frontend يستخدم فى التقاط البيانات المخرجة. يستخدم خاصية الـ output buffering التى تقدمها لغة PHP ليلتقط كل شئ يتم اخراجه بين الـ methods المسمى ()start و ()end.

4.3.2.2. الـ options المتوفرة

هذا الـ frontend لا يحتوى اى options جديدة بخلاف الموجودة فى Zend_Cache_Core.

4.3.2.3. امثلة

تم اعطاء مثال فى بداية هذا الفصل, ها هو مع بعض التعديلات الصغيرة:

<?php

// if it is a cache miss, output buffering is triggered
if(!$cache->start('mypage')):

// output everything as usual
echo 'Hello world! ';
echo 'This is cached ('.time().') ';

$cache->end(); // output buffering ends
endif;

echo 'This is never cached ('.time().').';

?>       

بإستخدام هذه الطريقة يمكنك بسهولة إدخال خاصية الـ caching لمخرجات الأكواد فى مشروعك بإستخدام القليل او ربما عدم الأحتياج لعمل refactoring.

4.3.3. Zend_Cache_Frontend_Function

4.3.3.1. مقدمة

تقوم Zend_Cache_Frontend_Function بعمل cache لناتج استدعاء دالة ما, و لديها method واحد رئيسى يسمى ()call و الذى يأخذ اسم الدالة المراد استدعائها و array تحتوتى الـ parameters التى سيتم تمريرها لهذه الدالة.

4.3.3.2. الـ options المتوفرة

جدول 4.2. الـ options المتوفرة لـ Zend_Cache_Frontend_Function

الـ Option الـ Data Type الـ Default Value الوصف
cacheByDefault boolean true إن كانت قيمتها true , سيتم تنفيذ عملية الـ cache لكل عملية استدعاء دالة (by default).
cachedFunctions array   اسماء الـ functions التى سيتم عمل cache لها دائما.
nonCachedFunctions array   اسماء الـ functions التى لا يجب عمل cache لها ابدا.

4.3.3.3. امثلة

استخدام الـ method المسمى ()call هو نفس طريقة استخدام دالة لغة PHP المسمى ()call_user_func_array :

<?php

$cache->call('veryExpensiveFunc', $params);

# $params is an array
# for example to call (with caching) veryExpensiveFunc(1, 'foo', 'bar'), you will use
# $cache->call('veryExpensiveFunc', array(1, 'foo', 'bar'))

?>       

Zend_Cache_Frontend_Function ذكية كفاية لتقوم بعمل cache لكل من ناتج الدالة العائد من "return" و البيانات المخرجة داخل الدالة (مثل عمل طباعة لبعض البيانات من داخل الدالة).

[ملاحظة] ملاحظة

يمكنك تمرير اى دالة سواء كانت من دوال اللغة او دالة انت انشئتها بإستثناء الدوال التالية : array, echo, empty, eval, exit, isset, list , print unset.

4.3.4. Zend_Cache_Frontend_Class

4.3.4.1. مقدمة

يختلف Zend_Cache_Frontend_Class عن Zend_Cache_Frontend_Function حيث انه يقوم بعمل cache لعمليات استدعاء الـ objects و الـ static methods.

4.3.4.2. الـ options المتوفر

جدول 4.3. الـ options المتوفرة لـ Zend_Cache_Frontend_Class

الـ Option الـ Data Type الـ Default Value الوصف
cachedEntity (مطلوب) mixed   إن كانت قيمتها عبارة عن اسم class, سيتم عمل cache للـ class على انه abstract و سيتم استخدام طلبات الـ static mithods الخاصة به. إذا كانت قيمتها عبارة عن object, سيتم عمل cache لكل الـ methods الخاصة بهذا الـ object.
cacheByDefault boolean true إن كانت تحمل القيمة true, كل الطلبات "calls" سيتم عمل cache لها تلقائيا.
cachedMethods array   اسماء الـ methods التى يستم عمل cache لها دائما.
nonCachedMethods array   اسماء الـ methods التى لا يجب عمل cache لها ابدا.

4.3.4.3. امثلة

مثال على عمل cache لأستدعائات الـ static methods:

<?php

class test {
   
    # Static method
    public static function foobar($param1, $param2) {
        echo "foobar_output($param1, $param2)";
        return "foobar_return($param1, $param2)";   
    }

}

// [...]
$frontendOptions = array(
    'cachedEntity' => 'test' // The name of the class
);
// [...]

# The cached call
$res = $cache->foobar('1', '2');

?>       

لعمل cache للـ methods العادية:

<?php

class test {
   
    private $_string = 'hello !';
      
    public function foobar2($param1, $param2) {
        echo($this->_string);
        echo "foobar2_output($param1, $param2)";
        return "foobar2_return($param1, $param2)";   
    }

}

// [...]
$frontendOptions = array(
    'cachedEntity' => new test() // An instance of the class
);
// [...]

# The cached call
$res = $cache->foobar2('1', '2');

?>       

4.3.5. Zend_Cache_Frontend_File

4.3.5.1. مقدمة

Zend_Cache_Frontend_File هو frontend يعتمد على اخر وقت تعديل ملف معين "master file". يتم استخدامه على سبيل المثال مع ملفات الـ configuration او الملفات التى تخص الـ templating.

على سبيل المثال: انت لديك ملف XML يحتوى على الـ configurations الخاصة ببرنامجك, هذا الملف يتم قرائة محتوياته بإستخدام دالة معينة و التى تعيد "return" إلينا "config object" (مثل Zend_Config ). عن طريق Zend_Cache_Frontend_File يمكنك حفظ الـ "config object" فى الـ cache (لتتجنب عملية قرائة ملف الـ XML عند كل مرة) لكن بالأعتماد بشدة على الـ "master file" اى ملف الـ XML. إذاً, إن تم تعديل ملف الـ XML سيتم اعتبار النسخة فى الـ cache غير صالحة للإستخدام و سيتم إنشاء اخرى جديدة.

4.3.5.2. الـ options المتوفرة

جدول 4.4. الـ options المتوفرة لـ Zend_Cache_Frontend_File

الـ Option الـ Data Type الـ Default Value الوصف
masterFile (إجبارى) string المسار الكامل للملف "master file".

4.3.5.3. امثلة

إستخدام هذا الـ frontend هو نفس طريقة استخدام Zend_Cache_Core, لذلك لا يوجد حاجة إلى مثال جديد, الشئ الوحيد الذى ستقوم به هو تعريف قيمة masterFile عند إستخدام الـ factory.

4.3.6. Zend_Cache_Frontend_Page

4.3.6.1. مقدمة

Zend_Cache_Frontend_Page يتشابه مع Zend_Cache_Frontend_Output إلا انه تم تصميمه لعمل cache لصفحة كاملة. فلا يمكن إستخدام Zend_Cache_Frontend_Page لعمل cache لجزء او بلوك معين فقط.

على الجانب الأخر, الـ "cache id" يتم حسابه من خلال ['SERVER['REQUEST_URI_$ و (اعتمادا على قيم الـ options يستخدم التالى) GET, POST, SESSION, COOKIE, FILES. غير ذلك, يجب عليك استدعاء method واحد فقط و هو (()start) لأن ()end يتم إستدعائه تلقائيا عند إنتهاء الصفحة.

الى هذه اللحظة لم يتم تنفيذه لكننا ننوى إضافة نظام HTTP شرطى لحفظ المذيد من الـ bandwith (سيقوم النظام بإرسال الهيدر "HTTP 304" أى لم يتم تعديل الملف و هذا إذا تم إيجاد نسخة cache قابلة للأستخدام "طازجة" و إذا كان لدى المتصفح ايضا نسخة صالحة "طازجة" من هذه الصفحة.

[ملاحظة] ملاحظة

Zend_Cache_Frontend_Page يعتبر فى المرحلة alpha الأن , إى انه سيتم عمل تطويرات جديدة له مع مرور الوقت.

4.3.6.2. الـ options المتوفرة

جدول 4.5. الـ options المتوفرة لـ Zend_Cache_Frontend_Page

الـ Option الـ Data Type الـ Default Value الوصف
httpConditional boolean false إستخدم نظام الـ HTTP الشرطى "httpConditional system" (لم يتم دعمه الى الأن).
debugHeader boolean false إن كانت تحمل القيمة true, بيانات الـ debugging سيتم إضافتها قبل كل صفحة لها cache.
defaultOptions array (.انظر الوصف.)array associative array تحتوى على الـ default options :
  • (boolean, true by default) cache : إن كانت تحمل قيمة true فالـ cache مفعل

  • (boolean, false by default) cacheWithGetVariables : إن كانت تحمل القيمة true فالـ cache مفعل حتى لو كان هناك قيم فى المصفوفة GET_$

  • (boolean, false by default) cacheWithPostVariables : إن كانت تحمل القيمة true فالـ cache مفعل حتى لو كان هناك قيم فى المصفوفة POST_$

  • (boolean, false by default) cacheWithSessionVariables : إن كانت تحمل القيمة true فالـ cache مفعل حتى لو كان هناك قيم فى المصفوفة SESSION_$

  • (boolean, false by default) cacheWithFilesVariables : إن كانت تحمل القيمة true فالـ cache مفعل حتى لو كان هناك قيم فى المصفوفة FILES_$

  • (boolean, false by default) cacheWithCookieVariables : إن كانت تحمل القيمة true فالـ cache مفعل حتى لو كان هناك قيم فى المصفوفة COOKIE_$

  • (boolean, true by default) makeIdWithGetVariables : إن كانت تحمل القيمة true فقيمة الـ "cache id" تعتمد على محتويات المصفوفة GET_$

  • (boolean, true by default) makeIdWithPostVariables : إن كانت تحمل القيمة true فقيمة الـ "cache id" تعتمد على محتويات المصفوفة POST_$

  • (boolean, true by default) makeIdWithSessionVariables : إن كانت تحمل القيمة true فقيمة الـ "cache id" تعتمد على محتويات المصفوفة SESSION_$

  • (boolean, true by default) makeIdWithFilesVariables : إن كانت تحمل القيمة true فقيمة الـ "cache id" تعتمد على محتويات المصفوفة FILES_$

  • (boolean, true by default) makeIdWithCookieVariables : إن كانت تحمل القيمة true فقيمة الـ "cache id" تعتمد على محتويات المصفوفة COOKIE_$

regexps array array() associative array تضع بها الـ options الخاصة بـ REQUEST_URI. المفتاح "key" سيكون عبارة عن جملة regex من النوع (PCRE), و القيم "values" ستكون عبارة عن associative array تحتوى مجموعة من الـ options التى سيتم تنفيذها إذا توافقت جملة الـ regex مع ['SERVER['REQUEST_URI_$ (انظر الى defaultOptions لقائمة بالـ options المتوفرة). إذا توافقت اكثر من جملة regexp مع قيمة ['SERVER['REQUEST_URI_$ , سيتم إستخدام اخر واحد فقط.

4.3.6.3. امثلة

إستخدام Zend_Cache_Frontend_Page سهل جدا :

<?php
	           
// [...] // require, configuration and factory
	
$cache->start();
// if the cache is hit, the result is sent to the browser and the script stop here
	
// rest of the page ...
	
?>       

مثال اكثر تعقيدا يوضح اسلوب لتنفيذ إدارة مركزية للـ cache داخل ملف bootstrap "ملف رئيسى لتشغيل البرنامج". (مثلا للإستخدام مع Zend_Controller)

<?php

// [...] you should avoid to put too much lines before the cache section 
// [...] for example, for optimal performances, "require_once" or "Zend_Loader::loadClass" should be 
// [...] after the cache section        	

require_once 'Zend/Cache.php';

$frontendOptions = array(
   'lifeTime' => 7200,
   'debugHeader' => true, // for debuging 
   'regexps' => array(
       '^/$' => array('cache' => true),         // cache the whole IndexController         
       '^/index/' => array('cache' => true),    // cache the whole IndexController
       '^/article/' => array('cache' => false), // we don't cache the ArticleController...
       '^/article/view/' => array(              // ...but we cache the "view" action of 
           'cache' => true,                     // this ArticleController
           'cacheWithPostVariables' => true,    // and we cache even there are some variables in $_POST
           'makeIdWithPostVariables' => true,   // (but the cache will be dependent of the $_POST array)
       )
   )	  
);
$backendOptions = array(
    'cacheDir' => '/tmp/' 
);

// getting a Zend_Cache_Frontend_Page object
$cache = Zend_Cache::factory('Page', 'File', $frontendOptions, $backendOptions);

$cache->start();
// if the cache is hit, the result is sent to the browser and the script stop here

// [...] the end of the bootstrap file (these lines won't be executed if the cache is hit)
	        	
?>