PHP OO deneme mantık uygulanması ve dinamik bir yöntem ve Değiştirgeleri geçen

6 Cevap php

Buradaki ilk soru.

Soru bu birine benzer: http://stackoverflow.com/questions/712161/php-retrying-a-query-a-set-number-of-times-or-until-success

Try till success in OO way. Here example what i'm trying to do:

class Reklamlar {

public function run() {
	$auth_token='mypassword';
	$id=123123;
	$this->retry_till_success ( $this->getCreatives, array($auth_token, $id) );
	print $this->creatives;	
}

public function getCreatives($auth_token, $id) {
	$this->creatives = $this->campagin->get($auth_token, $id);		
}

private function retry_till_success($method, $args) {
	do {
		$try_again = false;
		try {
			/* how to call the method with */
			/* call user method with params pass */
			/* do until success */
		} catch (SoapFault $fault) {
			if($fault->faultstring== 'couldnt connect to host')
				$try_again=true;
		}
	} while ($try_again);
}

}

i read about call_user_func, but don't know if i could use it inside the class, I need to make 99.9% success rate in my calls, any suggestion to achieve this will be great. thank you.

6 Cevap

En iyi yolu SoapClient genişletmek ve __ çağrı yöntemi yeniden deneme eklemek olacaktır.

class LocalSoapClient extends SoapClient
{

  public function __call($function_name, $arguments)
  {
    $result = false;
    $max_retries = 5;
    $retry_count = 0;

    while(! $result && $retry_count < $max_retries)
    {
      try
      {
        $result = parent::__call($function_name, $arguments);
      }
      catch(SoapFault $fault)
      {
        if($fault->faultstring != 'Could not connect to host')
        {
          throw $fault;
        }
      }
      sleep(1);
      $retry_count ++;
    }
    if($retry_count == $max_retries)
    {
      throw new SoapFault('Could not connect to host after 5 attempts');
    }
    return $result;
  }
}

o zaman sabun istemci kullanımını new LocalSoapClient() yerine örneğini zaman new SoapClient()

call_user_func_array() için bu harika:

$result = call_user_func_array( array($this, $method), $args );

İlk argüman geri pseudo-type, ve ikinci bireysel argümanlar olarak işlev / yöntem geçirilir parametreleri bir dizidir.

Bir yan not olarak, (örneğin, bir sınıra kadar başarısız her zaman iki katına bir uyku zaman var) ve yeniden deneme kısma bakmak isteyebilirsiniz. Host bağlantısı aşağı ise mümkün olduğunca hızlı yeniden denemeden çok nokta olmayabilir.

private function retry_till_success($method, $args) {

...

$this->$method($args[0], $args[1]);

}

Ayrıca ReflectionClass / ReflectionMethod kullanımı ve args değişken bir dizi için invokeArgs () diyebiliriz

http://nz.php.net/oop5.reflection

Ne demek istediğini pek emin değilim, ama bu () nasıl çalıştığını call_user_func (_array) olduğunu:

call_user_func($method, $arg); //call global function named $method like this: $method($arg)
call_user_func(array($this, $method), $arg); call class method on this class like this: $this->$method($arg);
//lets presume args is an array: $args = array(1, 2);
call_user_func_array($method, $args); //calls global function named $method like this: $method($args[0], $args[1]);
call_user_func_array(array($this, $method), $args); //calls class method like this: $this->$method($args[0], $args[1]);

Also see the documentation for call_user_func:
http://nl3.php.net/manual/en/function.call-user-func.php
and for call_user_func_array:
http://nl3.php.net/manual/en/function.call-user-func-array.php

$this->getCreatives PHP işlevleri nedeniyle çalışmayacak taban sınıf vatandaş değildir. Sen bir arabirim (yani iRepeatableTask) uygulayan bir nesne olarak her görevi call_user_func[_array] kullanabilir veya görevler için bir fabrika oluşturmak ve temsil edebilir. Böylece arayabilirsiniz

try
{    
    $task->repeatUntilSuccess()
} catch (SoapFault $e) {...}

ve avantajı, bu objecs (örneğin cronjob vb), daha sonra gerçekleştirmek için DB easy-to-save/restore olmasıdır.

İşte üretimde kullanıyorum benim son çözümdür.

    protected function retry_till_success($method, $args) {
	/*
	*	-1 : unrecoverable error
	* 	 0 : recoverable error
	* 	 1 : success
	*/
	$success = 0;
	$tries = 0;

	do {
		$tries++;
		$success = call_user_func_array( array($this, $method), $args );
		if ($success===0) {
			usleep(self::DELAY_MS);
		}
	} while ($success===0 && $tries < self::MAX_RETRIES);

	if ($tries >= self::MAX_RETRIES)
		return false;

	return true;
}