اذهب إلى المحتوى

التخزين المؤقت (Cache) ومقابس الويب (Webscockets) في PHP


سارة محمد2

التخزين المؤقت باستخدام memcache

Memcache هو نظام تخزين مؤقت للأغراض الموزعة يستخدم الزوج قيمة-مفتاح لتخزين البيانات الصغيرة، تحتاج أن تتأكد من أنّ Memcache مثبّتة قبل أن تستدعي شيفرتها في PHP، يمكنك القيام بذلك باستخدام تابع class_exists في PHP. بعد أن تتأكد من أنّها مثبّتة يمكنك الاتصال بنسخة خادم memcache.

if (class_exists('Memcache')) {
    $cache = new Memcache();
    $cache->connect('localhost',11211);
}else {
    print "Not connected to cache server";
}

ستتحقق هذه الشيفرة من أنّ محركات PHP للذاكرة Memcache مثبتة وتتصل إلى نسخة خادم memcache المُنفَّذ على الخادم المحلي. تعمل Memcache بشكلٍ خفي وتدعى memcached.

اتصلنا في المثال السابق إلى خادم واحد لكن يمكننا أيضًا الاتصال بعدة خوادم باستخدام الشيفرة:

if (class_exists('Memcache')) {
    $cache = new Memcache();
    $cache->addServer('192.168.0.100',11211);
    $cache->addServer('192.168.0.101',11211);
}

لاحظ أنّه في هذه الحالة لن يكون هناك أي اتصال نشط حتى تحاول تخزين قيمة أو جلبها، يوجد ثلاث عمليات أساسية التي نحتاج إلى تنفيذها في التخزين المؤقت:

  • تخزين البيانات: إضافة بيانات جديدة إلى خادم memcached.
  • الحصول على البيانات: جلب البيانات من خادم memcached.
  • حذف البيانات: حذف بيانات موجودة سابقًا على خادم memcached.

تخزين البيانات

يملك كائن الصنف memcached أو ‎$cache التابع set الذي يأخذ المعاملات (المفتاح والقيمة والوقت) لحفظ قيمة من أجل زمن الحياة (ttl).

$cache->set($key, $value, 0, $ttl);

‎$ttl أو زمن الحياة هنا مقدرًا بالثانية هو الزمن الذي تحتاجه memcache لتخزين الزوج على الخادم.

الحصول على البيانات

يملك كائن الصنف memcached أو ‎$cache التابع get الذي يأخذ مفتاح ويعيد القيمة المقابلة.

$value = $cache->get($key);

إذا لم توجد قيمة مقابلة للمفتاح ستُرجع القيمة null.

حذف البيانات

قد تحتاج أحيانًا إلى حذف بعض القيم من الذاكرة المخبئية، يملك كائن الصنف memcached أو ‎$cache التابع delete الذي يُستخدم لهذا الغرض:

$cache->delete($key);

سيناريو بسيط للتخزين المؤقت

بفرض لدينا مدونة بسيطة، ستوجد عدة منشورات في صفحة الهبوط تُجلب من قاعدة البيانات عند كل تحميل للصفحة، يمكننا استخدام memcached لتخزين المنشورات وذلك لتقليل استعلامات sql، إليك تنفيذ بسيط لذلك:

if (class_exists('Memcache')) {
    $cache = new Memcache();
    $cache->connect('localhost',11211);
    if(($data = $cache->get('posts')) != null) {
        // الحصول على البيانات من ذاكرة التخزين المؤقت
    } else {
        // فُقدت ذاكرة التخزين المؤقت، الاستعلام من قاعدة البيانات وحفظ النتائج إلى القاعدة
        // ‫بفرض ‎$posts مصفوفة المنشورات المُستعادة من قاعدة البيانات
        $cache->set('posts', $posts,0,$ttl);
    }
}else {
    die("Error while connecting to cache server");
}

التخزين المؤقت باستخدام APC

ذاكرة التخزين المؤقت البديلة في PHP (‏APC) مجانية وشيفرة تشغيل مفتوحة لذاكرة التخزين المؤقت في PHP، هدفها توفير إطار عمل مجاني ومفتوح وقوي لذاكرة التخزين المؤقت وتحسين شيفرة PHP الوسيطة.

طريقة التثبيت:

sudo apt-get install php-apc
sudo /etc/init.d/apache2 restart

إضافة ذاكرة التخزين المؤقت:

apc_add ($key, $value , $ttl);
$key = unique cache key
$value = cache value
$ttl = Time To Live;

حذف ذاكرة التخزين المؤقت:

apc_delete($key);

مثال عن ضبط الذاكرة المخبئية:

if (apc_exists($key)) {
    echo "Key exists: ";
    echo apc_fetch($key);
} else {
    echo "Key does not exist";
    apc_add ($key, $value , $ttl);
}

الأداء: APC أسرع من Memcached ب ‏5‏ مرات تقريبًا.

مقابس الويب (Webscockets)

ينفّذ استخدام إضافة المقبس (socket) واجهة منخفضة المستوى لدوال اتصال المقبس بالاعتماد على مقابس BSD (‏Berkeley Software Distribution) الشائعة، مما يوفر إمكانية العمل كخادم مقبس وعميل.

خادم TCP/IP بسيط

يمكنك أن تجد هنا مثالًا بسيطًا يعتمد على توثيق PHP الرسمي.

أنشئ سكربت مقبس ويب يستمع إلى المنفذ 5000 باستخدام putty والطرفية لتنفيذ الأمر telnet 127.0.0.1 5000 (المضيف المحلي)، يرد هذا السكربت بالرسالة التي أرسلتها (كتعقب عكسي):

<?php
// تعطيل المهلة
set_time_limit(0); 
// تعطيل التخزين المؤقت للخرج
ob_implicit_flush(); 

// الإعدادات
$address = '127.0.0.1';
$port = 5000;

// (1)
if (($socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
    echo "Couldn't create socket".socket_strerror(socket_last_error())."\n";
}

// (2)
if (socket_bind($socket, $address, $port) === false) {
    echo "Bind Error ".socket_strerror(socket_last_error($sock)) ."\n";
}

if (socket_listen($socket, 5) === false) {
    echo "Listen Failed ".socket_strerror(socket_last_error($socket)) . "\n";
}

do {
    if (($msgsock = socket_accept($socket)) === false) {
        echo "Error: socket_accept: " . socket_strerror(socket_last_error($socket)) . "\n";
        break;
    }

    /* إرسال رسالة ترحيب */
    $msg = "\nPHP Websocket \n";

    // الاستماع إلى دخل المستخدم
    do {
        if (false === ($buf = socket_read($msgsock, 2048,         PHP_NORMAL_READ))) {
            echo "socket read error: ".socket_strerror(socket_last_error($msgsock)) . "\n";
            break 2;
        }
        if (!$buf = trim($buf)) {
            continue;
        }
        // الرد على المستخدم برسالته
        $talkback = "PHP: You said '$buf'.\n";
        socket_write($msgsock, $talkback, strlen($talkback));
        // طباعة الرسالة على الطرفية
        echo "$buf\n";
    } while (true);
    socket_close($msgsock);
} while (true);
socket_close($socket);
?>

في الموضع (1) لدينا الدالة socket_create لها الشكل العام ( int $domain , int $type , int $protocol ):

  • يمكن أن يكون المتغير ‎$domain هو AF_INET أو AF_INET6 من أجل IPV6 أو AF_UNIX من أجل بروتوكول الاتصال المحلي.
  • يمكن أن يكون المتغير ‎$protocol إما SOL_TCP أو SOL_UDP ‏(TCP/UDP) تعيد هذه الدالة القيمة true في حالة النجاح.

في الموضع (2) نستخدم الدالة socket_bind التي تربط هذه الدالة المقبس ليستمع إلى عنوان ومنفذ محددين ولها الشكل العام:

socket_bind ( resource $socket , string $address [, int $port = 0 ] )‎

استيثاق HTTP

سنكتب سكربت استيثاق ترويسة HTTP بسيط، ولاحظ أنّه يجب وضع هذه الشيفرة في ترويسة الصفحة وإلا لن يعمل:

<?php
if (!isset($_SERVER['PHP_AUTH_USER'])) {
    header('WWW-Authenticate: Basic realm="My Realm"');
    header('HTTP/1.0 401 Unauthorized');
    echo 'Text to send if user hits Cancel button';
    exit;
}

echo "<p>Hello {$_SERVER['PHP_AUTH_USER']}.</p>";
// حفظ المعلومات
$user = $_SERVER['PHP_AUTH_USER']; 
echo "<p>You entered {$_SERVER['PHP_AUTH_PW']} as your password.</p>";

// ‫حفظ كلمة المرور (يمكن إضافة التشفير اختياريًا)
$pass = $_SERVER['PHP_AUTH_PW']; //Save the password(optionally add encryption)!
?>
// ‫صفحة html

ترجمة -وبتصرف- للفصول [Cache - WebSockets - HTTP Authentication] من كتاب PHP Notes for Professionals book

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...