帮助PHP call_user_func和集成函数到类? [英] Help with PHP call_user_func and integrate function into Class?

查看:73
本文介绍了帮助PHP call_user_func和集成函数到类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是一个我一年前发现的一个函数,它应该锁定一个内存缓存键,所以你可以更新它的值,没有任何麻烦的2请求尝试更新密钥在同一时间。



这是非常基本的,但我可以使用一点帮助,弄清楚如何使用它100%。我不确定的部分是在 $ updateFunction 中传递的部分,然后传递给**

  call_user_func($ updateFunction,$ data); //更新数据

我从来没有使用过call_user_func()。基于这段代码可以告诉我一个基本的例子,它调用的函数可能看起来像(没有做任何mysql或任何东西,只是它的工作方式)。我能够将多个属性传递给调用函数吗?



感谢您的帮助。还假设我已经有一个类名Memcache有一个连接或对象与此 $ this->连接,我需要更改任何东西在下面的功能添加到我的Memcache类中?此外,一旦这个函数是我现有的memcache类的一部分,那个回调函数能否在其他类中调用方法?



希望这不要混淆。

  // {{{locked_mecache_update($ memcache,$ key,$ updateFunction,$ expiryTime,$ waitUTime,$ maxTries)
/ **
*确保只有一件事可以一次更新内存缓存的函数。
*
*请注意,memcache的$ expiryTime不是
*足够的问题,但这是我能做的最好的。这种形式
*锁定的背后的想法是,它利用了事实,
* {@link memcache_add()}本质上是原子的。
*
*简单地通过存储时间戳或
* something可以是一个更有趣的限制器(比如限制
*更新不超过1 /秒)的性质与锁定键(当前存储1)和
*不取消内存缓存条目。
*
* @param $ memcache memcache memcache对象
* @param $ key字符串在
* @param $ updateFunction混合函数调用从memcache接受数据
*并修改它(使用传递引用)。
* @param $ expiryTime允许密钥在
*之前的整数时间(以秒为单位),它将过期。这只有在更新过程中死亡时才会发生。
*选择一个足够大的数字,以便$ updateFunction将花费更少的
*时间来执行。
* @param $ waitUTime integer等待的时间量(以微秒为单位)
*检查锁定释放
* @param $ maxTries整数最大尝试次数之前它放弃
*上的锁。注意,如果$ maxTries为0,那么它将RickRoll永远
*(永不放弃)。默认数字确保它会等待三个
*完全锁定周期崩溃,在它放弃之前。
* @return boolean成功或失败
* /
function locked_memcache_update(
$ memcache,// Memcache Object
$ key,//更新的键
$ updateFunction,//将键/值传递给更新的函数
$ expiryTime = 3,//键到期前的时间
$ waitUtime = 101,//等待检查锁定释放的时间
$ maxTries = 100000)//尝试获取锁的次数
{

$ lock ='lock:'。

//获取锁{{{
if($ maxTries> 0){
for($ attempts = 0; $ attempts< $ maxTries; ++ $ attempts) {
if($ memcache-> add($ lock,1,0,$ expiryTime)){break; }
usleep($ waitUtime);
}
if($ attempts == $ maxTries){
//处理失败的情况(使用异常和try-catch如果你需要很好)
trigger_error(sprintf '锁定失败的键:%s',$ key),E_USER_NOTICE);
return false;
}
} else {
while(!$ memcache-> add($ lock,1,0,$ expiryTime)){
usleep($ waitUtime);
}
}
//}}}

//现在我们有一个锁,所以我们可以更新key / value
//修改数据in cache {{{
$ data = $ memcache-> get($ key,$ flag);
call_user_func($ updateFunction,$ data); // update data
$ memcache-> set($ key,$ data,$ flag);
//}}}

//更新完成所以我们释放锁
//清除锁
$ memcache-> delete($ lock,0 );
返回true;
}
//}}}
?>






UPDATE p>

这是我现有的Memcache类,我想将其与

集成。

 <?PHP 
class MemCache
{

// Memcache对象
public $ connection;

function __construct()
{
$ this-> connection = new MemCache;
}

//将键/值设置为memcache到期时间
函数存储($ key,$ data,$ ttl)
{
return $ this-> connection-> set($ key,$ data,0,$ ttl);
}

//使用KEY从存储缓存检索值
函数fetch($ key)
{
return $ this-> connection- > get($ key);
}

//使用KEY删除Memcache中的键/值
函数delete($ key)
{
return $ this-> connection-> delete($ key);
}

//为memcache添加服务器连接
function addServer($ host,$ port = 11211,$ weight = 10)
{
$ this-> connection-> addServer($ host,$ port,true,$ weight);
}

//清除所有memcache数据
function flush()
{
return $ this-> connection-> flush
}

//显示Memcache统计信息
function stats()
{
return statDetails($ this-> connection-> getStats );
}

//在表中显示Memcache统计信息
function statDetails($ status)
{
echo< table border ='1' >;
echo< tr>< td> Memcache服务器版本:< / td>< td>。 $ status [version]。
< / td>< / tr>;
echo< tr>< td>此服务器进程的进程ID< / td>< td> 。 $ status [pid]。
< / td>< / tr>;
echo< tr>< td>此服务器已运行的秒数< / td>< td> 。 $ status [uptime]。
< / td>< / tr>;
echo< tr>< td>此过程的累计用户时间< / td>< td> 。 $ status [rusage_user]。
seconds< / td>< / tr>;
echo< tr>< td>此过程的累计系统时间< / td>< td> 。 $ status [rusage_system]。
seconds< / td>< / tr>;
echo< tr>< td>此服务器自启动以来存储的项目总数< / td>< td> 。
$ status [total_items]。 < / td>< / tr>;
echo< tr>< td>打开的连接数量< / td>< td> 。 $ status [curr_connections]。
< / td>< / tr>;
echo< tr>< td>自服务器开始运行以来打开的连接总数< / td>< td> 。
$ status [total_connections]。 < / td>< / tr>;
echo< tr>< td>由服务器分配的连接结构数< / td>< td> 。
$ status [connection_structures]。 < / td>< / tr>;
echo< tr>< td>检索要求的累计次数< / td>< td> 。 $ status [cmd_get]。
< / td>< / tr>;
echo< tr>< td>累积存储请求数< / td>< td> 。 $ status [cmd_set]。
< / td>< / tr>;
$ percCacheHit =((real)$ status [get_hits] /(real)$ status [cmd_get] * 100);
$ percCacheHit = round($ percCacheHit,3);
$ percCacheMiss = 100 - $ percCacheHit;
echo< tr>< td>已请求并查找到的键数目< / td>< td> 。
$ status [get_hits]。 ($ percCacheHit%)< / td>< / tr>;
echo< tr>< td>已请求并未找到的项目数量< / td>< td> 。
$ status [get_misses]。 ($ percCacheMiss%)< / td>< / tr>;
$ MBRead =(real)$ status [bytes_read] /(1024 * 1024);
echo< tr>< td>此服务器从网络读取的字节总数< / td>< td> 。
$ MBRead。 Mega Bytes< / td>< / tr>;
$ MBWrite =(real)$ status [bytes_written] /(1024 * 1024);
echo< tr>< td>此服务器发送到网络的字节总数< / td>< td> 。
$ MBWrite。 Mega Bytes< / td>< / tr>;
$ MBSize =(real)$ status [limit_maxbytes] /(1024 * 1024);
echo< tr>< td>此服务器允许用于存储的字节数。< / td>< td> 。
$ MBSize。 Mega Bytes< / td>< / tr>;
echo< tr>< td>从缓存中删除的新项目的空闲内存的数量< / td>< td> 。
$ status [evictions]。 < / td>< / tr>;
echo< / table>;
}

}

?>


解决方案

c> c $>的文档.net / manual / en / function.call-user-func.phprel =nofollow noreferrer 回调伪类型。简而言之,它是一个函数名或数组。数组必须包含两个字符串(类名和函数名 - 静态函数的回调)或对象和字符串(对象和调用该对象的方法 - 用于成员函数)。以下是文档中的示例:


 <?php 
$ b b //一个示例回调函数
function my_callback_function(){
echo'hello world!';
}

//示例回调方法
class MyClass {
static function myCallbackMethod(){
echo'Hello World!';
}
}

//类型1:简单回调
call_user_func('my_callback_function');


//类型2:静态类方法调用
call_user_func(array('MyClass','myCallbackMethod'));

//类型3:对象方法调用
$ obj = new MyClass();
call_user_func(array($ obj,'myCallbackMethod'));

//类型4:静态类方法调用(从PHP 5.2.3开始)
call_user_func('MyClass :: myCallbackMethod');

//类型5:相对静态类方法调用(从PHP 5.3.0开始)
类A {
public static function who(){
echo一个;
}
}

class B extends A {
public static function who(){
echoB \\\
;
}
}

call_user_func(array('B','parent :: who')); // A
?>


还有一件事:你的锁定可以是中断 add($ lock,... get()。使用 increment() decrement() 可以解决这个问题。


Below is a function I found about a year ago that is supposed to put a lock on a memcache key so you can update it's value without any trouble of 2 request trying to update the key at the same time.

It is pretty basic but I could use a little help in figuring out how to use it 100%. The part I am not sure about is where it passes in a $updateFunction which is then passed to **

call_user_func($updateFunction, $data); // update data

I have never used the call_user_func() before. Based on this code could some one show me a basic example of what a function that it calls could look like (without doing any mysql or anything, just the way it would work). Would I be able to pass in multiple properties to the call function?

Thanks for any help. Also assuming I already have a Class name Memcache which has a connection or object with this $this->connection would I need to change anything in the function below to add it into my Memcache class? Also once this function is part of my existing memcache class, will that callback function be able to call methods in other classes?

Hope this isn't to confusing.

// {{{ locked_mecache_update($memcache,$key,$updateFunction,$expiryTime,$waitUTime,$maxTries)
/**
 * A function to do ensure only one thing can update a memcache at a time.
 *
 * Note that there are issues with the $expiryTime on memcache not being
 * fine enough, but this is the best I can do. The idea behind this form
 * of locking is that it takes advantage of the fact that
 * {@link memcache_add()}'s are atomic in nature.
 *
 * It would be possible to be a more interesting limiter (say that limits
 * updates to no more than 1/second) simply by storing a timestamp or
 * something of that nature with the lock key (currently stores "1") and
 * not deleitng the memcache entry.
 *
 * @param $memcache memcache the memcache object
 * @param $key string the key to do the update on
 * @param $updateFunction mixed the function to call that accepts the data
 *  from memcache and modifies it (use pass by reference).
 * @param $expiryTime integer time in seconds to allow the key to last before
 *  it will expire. This should only happen if the process dies during update.
 *  Choose a number big enough so that $updateFunction will take much less
 *  time to execute.
 * @param $waitUTime integer the amount of time in microseconds to wait before
 *  checking for the lock to release
 * @param $maxTries integer maximum number of attempts before it gives up
 *  on the locks. Note that if $maxTries is 0, then it will RickRoll forever
 *  (never give up). The default number ensures that it will wait for three
 *  full lock cycles to crash before it gives up also.
 * @return boolean success or failure
 */
function locked_memcache_update(
    $memcache,          // Memcache Object
    $key,               // Key to update
    $updateFunction,   // Function to pass key/value into to update
    $expiryTime=3,     // time before key expires
    $waitUtime=101,    // time to wait for to check for lock release
    $maxTries=100000) //  number of times to try to get lock
    {

    $lock = 'lock:'.$key;

    // get the lock {{{
    if ($maxTries>0) {
        for ($tries=0; $tries< $maxTries; ++$tries) {
            if ($memcache->add($lock,1,0,$expiryTime)) { break; }
            usleep($waitUtime);
        }
        if ($tries == $maxTries) {
            // handle failure case (use exceptions and try-catch if you need to be nice)
            trigger_error(sprintf('Lock failed for key: %s',$key), E_USER_NOTICE);
            return false;
        }
    } else {
        while (!$memcache->add($lock,1,0,$expiryTime)) {
            usleep($waitUtime);
        }
    }
    // }}}

    //Now we have a lock so we can update of key/value
    // modify data in cache {{{
    $data = $memcache->get($key, $flag);
    call_user_func($updateFunction, $data); // update data
    $memcache->set($key, $data, $flag);
    // }}}

    // Update complete so we release our lock
    // clear the lock
    $memcache->delete($lock,0);
    return true;
}
// }}}
?>


UPDATE

Here is my existing Memcache class that I would like to integrate this with

<?PHP
class MemCache
{

    // Memcache object
    public $connection;

    function __construct()
    {
        $this->connection = new MemCache;
    }

    // Set a key/value to memcache with Expire time
    function store($key, $data, $ttl)
    {
        return $this->connection->set($key, $data, 0, $ttl);
    }

    // Retrieve a Value from Memcache with a KEY
    function fetch($key)
    {
        return $this->connection->get($key);
    }

    // DELETE a Key/Value from Memcache with a KEY
    function delete($key)
    {
        return $this->connection->delete($key);
    }

    // Add a server connection to memcache
    function addServer($host, $port = 11211, $weight = 10)
    {
        $this->connection->addServer($host, $port, true, $weight);
    }

    // Clear all memcache data
    function flush()
    {
        return $this->connection->flush();
    }

    // Show Memcache stats
    function stats()
    {
        return statDetails($this->connection->getStats());
    }

    // Show Memcache stats in a table
    function statDetails($status)
    {
        echo "<table border='1'>";
        echo "<tr><td>Memcache Server version:</td><td> " . $status["version"] .
            "</td></tr>";
        echo "<tr><td>Process id of this server process </td><td>" . $status["pid"] .
            "</td></tr>";
        echo "<tr><td>Number of seconds this server has been running </td><td>" . $status["uptime"] .
            "</td></tr>";
        echo "<tr><td>Accumulated user time for this process </td><td>" . $status["rusage_user"] .
            " seconds</td></tr>";
        echo "<tr><td>Accumulated system time for this process </td><td>" . $status["rusage_system"] .
            " seconds</td></tr>";
        echo "<tr><td>Total number of items stored by this server ever since it started </td><td>" .
            $status["total_items"] . "</td></tr>";
        echo "<tr><td>Number of open connections </td><td>" . $status["curr_connections"] .
            "</td></tr>";
        echo "<tr><td>Total number of connections opened since the server started running </td><td>" .
            $status["total_connections"] . "</td></tr>";
        echo "<tr><td>Number of connection structures allocated by the server </td><td>" .
            $status["connection_structures"] . "</td></tr>";
        echo "<tr><td>Cumulative number of retrieval requests </td><td>" . $status["cmd_get"] .
            "</td></tr>";
        echo "<tr><td> Cumulative number of storage requests </td><td>" . $status["cmd_set"] .
            "</td></tr>";
        $percCacheHit = ((real)$status["get_hits"] / (real)$status["cmd_get"] * 100);
        $percCacheHit = round($percCacheHit, 3);
        $percCacheMiss = 100 - $percCacheHit;
        echo "<tr><td>Number of keys that have been requested and found present </td><td>" .
            $status["get_hits"] . " ($percCacheHit%)</td></tr>";
        echo "<tr><td>Number of items that have been requested and not found </td><td>" .
            $status["get_misses"] . "($percCacheMiss%)</td></tr>";
        $MBRead = (real)$status["bytes_read"] / (1024 * 1024);
        echo "<tr><td>Total number of bytes read by this server from network </td><td>" .
            $MBRead . " Mega Bytes</td></tr>";
        $MBWrite = (real)$status["bytes_written"] / (1024 * 1024);
        echo "<tr><td>Total number of bytes sent by this server to network </td><td>" .
            $MBWrite . " Mega Bytes</td></tr>";
        $MBSize = (real)$status["limit_maxbytes"] / (1024 * 1024);
        echo "<tr><td>Number of bytes this server is allowed to use for storage.</td><td>" .
            $MBSize . " Mega Bytes</td></tr>";
        echo "<tr><td>Number of valid items removed from cache to free memory for new items.</td><td>" .
            $status["evictions"] . "</td></tr>";
        echo "</table>";
    }

}

?>

解决方案

The documentation of call_user_func() contains a link to the callback pseudo-type. In short it is either a function name or an array. The array must either contain two strings (a class name and a function name - callback for static functions) or an object and a string (an object and the method to call on that object - for member functions). Here are the examples from the documentation:

<?php 

// An example callback function
function my_callback_function() {
    echo 'hello world!';
}

// An example callback method
class MyClass {
    static function myCallbackMethod() {
        echo 'Hello World!';
    }
}

// Type 1: Simple callback
call_user_func('my_callback_function');


// Type 2: Static class method call
call_user_func(array('MyClass', 'myCallbackMethod')); 

// Type 3: Object method call
$obj = new MyClass();
call_user_func(array($obj, 'myCallbackMethod'));

// Type 4: Static class method call (As of PHP 5.2.3)
call_user_func('MyClass::myCallbackMethod');

// Type 5: Relative static class method call (As of PHP 5.3.0)
class A {
    public static function who() {
        echo "A\n";
    }
}

class B extends A {
    public static function who() {
        echo "B\n";
    }
}

call_user_func(array('B', 'parent::who')); // A
?>

One more thing: Your locking could be interrupted between add($lock,... and get(). Using increment() and decrement() would solve that problem.

这篇关于帮助PHP call_user_func和集成函数到类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆