Tag Archives: php

PHP atomic update implement with memcache add

Problem
memcache_set is not atomic function
Cache news:
Key = news_134 (134 is news id)
Value = array(‘id’ => 134, ‘title’ => ‘huypv is a web developer’, ‘sapo” => ‘bla bla’, …., ‘view_count’ => 134);
When have guests read news 134 at the same time, the view_count is updated but not correct!

Solution
Create function updateViewCount and make it is atomic
function updateViewCount($id, $inc = 1) {
global $objMemcacheConnId;
$timeout = 15; // TODO change for your scene
$cacheKey = ‘news_’ . $id;
$lockKey = $cacheKey . ‘.lock’;
$getLock = memcache_add($objMemcacheConnId, $lockKey, 1, false, $timeout);
while (!$getLock) {
$getLock = memcache_add($objMemcacheConnId, $lockKey, 1, false, $timeout);
$nbTry++;
usleep(1); // micro second. 1 second = 10^6 micro second (1 milion)
if ($nbTry >= $timeout * 1000000) break;
}
if ($getLock) {
$currentNews = memcache_get($objMemcacheConnId, $cacheKey);
if ($currentNews) {
$newNews = $currentNews;
$newNews[‘view_count’] += $inc;
memcache_set($objMemcacheConnId, $cacheKey, $newNews);
memcache_delete($objMemcacheConnId, $lockKey); # release lock
return true;
} else {
return false; # not found
}
} else {
return false; # timeout
}
}

How to test? Does it work?
Use ab (apache benchmark) or multiple curl to send concurrent request.

Gọi SOAP bằng PHP, hàm có tham số phức tạp

var_dump($soapClient->__getFunctions(), $soapClient->__getTypes());
-> để lấy được thông tin hàm, định dạng tham số truyền vào
function f(T1 $parameters)
struct T1 {
T11 a;
string b;
}
struct T11 {
int c;
string d;
}

Khi đó cứ theo struct mà bên trong chỉ chứa các kiểu dữ liệu nguyên thủy (string, number), ta sẽ khai báo ngược lên để có được tham số tương ứng:
$t11 = array(‘c’ => 12, d => ‘twelve’);
$parameters = array(‘a’ => $t11, ‘b’ => ‘valid string’);
$soapClient->__soapCall(array($parameters)); # phải bọc $parameters trong array

Lệnh if chạy như thế nào?

PHP:
if (true || 1/0 != 2) {
echo ‘I am OK!’;
}

Java:
if (true || 1/0 != 2) {
System.out.println(“I am OK!”);
}

Cả 2 khối lệnh trên đều chạy được, như vậy thực sự 1/0 chưa “bị” gọi đến và vì thế mà không thấy thông báo lỗi “Division by zero”

Sắp xếp mảng theo độ dài xâu của phần tử

# CODE:
$arr = array(“0001”, “2”, “03”, “00004”);
usort($arr, ‘compare_length’);

var_dump($arr);

# OUTPUT
array(4) {
[0]=>
string(1) “2”
[1]=>
string(2) “03”
[2]=>
string(4) “0001”
[3]=>
string(5) “00004”
}

function compare_length($s1, $s2) {
$l1 = strlen($s1);
$l2 = strlen($s2);
if ($l1 == $l2) return 0;
return ($l1 < $l2) ? -1 : 1; }

Đôi khi muốn cho server nghỉ

User – URL [.htacess, mod_rewrite] – index.php [route] – path/script-will-be-exec.php [access DB] – data [template] – HTML

Chèn vào đầu file index.php:
if (file_exists(‘offline’)) {
echo ‘Offline!’;
exit(0);
}

// current code

Và thế là mỗi khi muốn làm gì đó (update/upload code, upgrade version, fix bug…), chỉ cần: touch offline
Cách này hay hơn so với:
– Offline nhờ thiết lập cấu hình trong db
– Offline bằng cách tạo index.html và cấu hình ưu tiên index.html lớn hơn index.php (user nhập hẳn index.php thì sao)