2014-10-09 226 views
0

我正在處理某人的代碼。代碼中有一個函數。foreach循環中對象的重新實例化

它像以下:

function send_notification($device_token) 
{ 
    $apn = new APN(); 
    $apn->payloadMethod = 'enhance'; // you can turn on this method for debuggin purpose 
    $apn->connectToPush(); 
    ............................ 
    ............................ 
} 

然後foreach循環裏面,他調用該函數。

foreach($alluser as $user) 
{ 
    send_notification($user['device_token']); 
} 

現在,如果我運行上面的代碼,那麼它說APN Failed to connect: Something wrong with context

所以我在代碼中改變了一些東西。

$apn = new APN(); 
foreach($alluser as $user) 
{ 
    $apn->payloadMethod = 'enhance'; // you can turn on this method for debuggin purpose 
    $apn->connectToPush(); 
    ............................ 
    ............................ 
} 

我創建foreach循環之外的類的對象然後它工作。
但事實是,我必須在每個地方編寫上面的代碼(本頁面包含其他foreach)。

那麼我怎麼才能以一種聰明的方式解決上述問題?

FULL CODE (Just some part)

<?php 
foreach($alluser as $user) 
{ 
    send_notification($user['device_token']); 
} 

function send_notification($device_token) 
{ 
    $apn = new APN(); 
    $apn->payloadMethod = 'enhance'; // you can turn on this method for debuggin purpose 
    $apn->connectToPush(); 
    ............................ 
    ............................ 
} 
?> 

旁註:什麼,我想知道的是,當我每次創建新的類實例,那麼爲什麼它不工作?

+2

沒有重新聲明班級。另外,你最後的努力工作? – sectus 2014-10-09 06:39:06

+0

我不知道該怎麼稱呼它,你可以編輯標題。我知道在foreach循環中,如果我調用函數,那麼它每次都會創建類的新實例。 – DS9 2014-10-09 06:44:28

+0

你最後的努力工作? – sectus 2014-10-09 06:56:31

回答

1

你可以只讓APN比如你功能的必需參數和之前的唯一實例循環。

<?php 
$apn = new APN(); 
foreach($alluser as $user) 
{ 
    send_notification($user['device_token'], $apn); 
} 

function send_notification($device_token, APN $apn) 
{ 
    $apn->payloadMethod = 'enhance'; // you can turn on this method for debuggin purpose 
    $apn->connectToPush(); 
    ............................ 
    ............................ 
} 

另一種方法是使用一個單身:

class APN { 
    private static $instance = null; 
    public static function getInstance() { 
     if (null === self::$instance) { 
      self::$instance = new self; 
     } 
     return self::$instance; 
    } 
    //.... whatever your class does 
} 

foreach($alluser as $user) 
{ 
    send_notification($user['device_token'], $apn); 
} 

function send_notification($device_token) 
{ 
    $apn = APN::getInstance(); 
    $apn->payloadMethod = 'enhance'; // you can turn on this method for debuggin purpose 
    $apn->connectToPush(); 
    ............................ 
    ............................ 
} 

艱難的注意,Singleton pattern還帶有其缺點一樣緊耦合,這使得測試更加努力,也隱藏依賴關係:

Singleton Antipattern

所以我的建議將是第一種方法。

+0

感謝您的回答。它是有益的。但是我不明白的是,當我每次創建類的新實例時,爲什麼它不起作用? – DS9 2014-10-09 08:23:33

+0

爲此,我們需要知道APN的代碼。也許它實現了一些鎖定,防止在關閉現有連接之前再次實例化。但在這裏,我只是猜測。 – enricog 2014-10-09 08:27:31

+0

[APN LIBRARY](https://github.com/antongorodezkiy/codeigniter-apns/blob/master/application/library/apn.php) – DS9 2014-10-09 08:42:23

1

您可以使用使用對象全局,那麼你不需要一次又一次地創建對象,例如

<?php 
$apn = new APN(); 
foreach($alluser as $user) 
{ 
    send_notification($user['device_token']); 
} 

function send_notification($device_token) 
{ 
    global $apn; 
    $apn->payloadMethod = 'enhance'; // you can turn on this method for debuggin purpose 
    $apn->connectToPush(); 
    ............................ 
    ............................ 
} 
?> 
+0

請不要使用全局變量,如果涉及到代碼的調試和理解,它們是非常糟糕的。 – enricog 2014-10-09 08:06:12