2017-02-15 75 views
0

我想在php中構建JSON服務器響應。在服務器運行腳本時,我在輸出中使用了一個數組來跟蹤腳本中的錯誤和成功。就像下面的代碼一樣。通過引用PHP集類成員

<?php 
$output = array(); 
$output["success"] = array(); 
$output["error"] = array(); 

public function foo(){ 
    global $output; 
    $db = database::getInstance(); //initialize singleton instance 
    $db->setOutput($output);  //set Output log 
    $db->login();     //log user in 

    $output["success"][] = "method end"; //debug breakpoint 
} 

echo json_encode($output, JSON_HEX_QUOT | JSON_HEX_TAG); 

和數據庫類看起來是這樣的......

<?php 
namespace db; 
class database{ 
    private var $output_log; 

    public function setOutputLog(&$output){ 
     $this->output_log = $output; 
    } 

    public function login(){ 
     ... 

     $this->output_log["error"][] = "login error"; 

     ... 
    } 
} 

而且當我運行該腳本的輸出總是這樣的事情...

{ 
    "success" : ["method end"], 
    "error" : [] 
} 

的問題似乎是當我嘗試通過引用數據庫類的單例實例或在調用json_encode()時傳遞$ output時。我已經看遍了,這是通過引用傳遞的唯一方法,但有趣的是,如果數據庫中存在錯誤,那麼JavaScript中的JSON.parse()將引發錯誤,並且輸出不是php錯誤登錄。無論如何,通過傳遞參考$output來解決這個問題,因爲有時候我希望$輸出變得相當大,並且我想保持數組的副本爲最小值,而且我真的不擅長php數組功能加上,如果我做了這樣的事情。 $ output [「error」] [] = $ db-> login(); 和更改的登錄方法返回$output_log我會最終與此。

{ 
    "success" : ["method end"], 
    "error" : ["error":["login error"]] 
} 

編輯: 的變化我萬一有人需要它使基地在你的答案。我繼續做了一個響應命名空間,其中兩個類將會讓我的生活變得更容易。

Response.php

namespace response; 
class json_builder 
{ 
    private static $instance; 
    private $output; 

    private function __construct(){ 
     $this->output = array(); 
    } 

    public static function getInstance(){ 
     if(is_null(self::$instance)){ 
      self::$instance = new self(); 
     } 
     return self::$instance; 
    } 

    public function addLine($tag, $msg){ 
     $this->output[$tag] = $msg; 
    } 

    public function remove($tag){ 
     unset($this->output[$tag]); 
    } 

    public function addArray($tag){ 
     $this->output[$tag] = array(); 
    } 

    public function addArrayLine($tag, $msg){ 
     array_push($this->output[$tag], $msg); 
    } 

    public function export($filter){ 
     echo json_encode($this->output, $filter); 
     unset($this->output); 
    } 
} 

class xml_builder 
{ 
    private static $instance; 
    private $output; 

    private function __construct(){ 
     $this->output = "<?xml version=\"1.0\"?>"; 
    } 

    public static function getInstance(){ 
     if(is_null(self::$instance)){ 
      self::$instance = new self(); 
     } 
     return self::$instance; 
    } 

    public function addNode($tag, $msg, $attributes){ 
     $this->output += ($attributes) ? "<"+$tag+" "+$attributes+">" : "<"+$tag+">"; 
     $this->output += $msg + "</"+$tag+">"; 
    } 

    public function startNode($tag, $msg, $attributes){ 
     $this->output += ($attributes) ? "<"+$tag+" "+$attributes+">" : "<"+$tag+">"; 
    } 

    public function endNode($tag){ 
     $this->output += "</"+$tag+">"; 
    } 

    public function addInput($msg){ 
     $this->output += $msg; 
    } 

    public function export(){ 
     echo $this->output; 
     unset($this->output); 
    } 
} 

,並從之前的新的代碼看起來像這樣

valid.php - >起點

<?php 
require_once "response.php"; 
require_once "db.php"; 

$output = /response/json_builder::getInstance(); 
$output->addArray("success"); 
$output->addArray"error"); 

public function foo(){ 
    $output = /response/json_builder::getInstance(); 
    $db = database::getInstance(); //initialize singleton instance 
    $db->login();     //log user in 

    $output->addArrayLine("success", "method end"); //debug breakpoint 
} 

$output->export(JSON_HEX_QUOT | JSON_HEX_TAG); 

db.php中 - >數據庫類

<?php 
namespace db; 
class database{ 
    private $xml_output; 
    private $json_output; 

    private function __construct() 
    { 
     $this->json_output = \response\json_builder::getInstance(); 
     $this->xml_output = \response\xml_builder::getInstance(); 
    } 

    public static function getInstance() 
    { 
     if(is_null(self::$instance)) 
     { 
       self::$instance = new self(); 
     } 
     return self::$instance; 
    } 

    public function login(){ 
     ... 

     $this->output->addArrayLine("error", "login error"); 

     ... 
    } 
} 

感謝幫助嚮導和克里斯。 =)

回答

0

嘗試將其設置爲:

public function setOutputLog(&$output){ 
    $this->output_log = &$output; 
} 

但全局變量是邪惡的:)

+0

是的,我只是想出來,它工作大聲笑,但我現在有一個新問題,我可以弄清楚如何正確地在我的數組中的數組值。 ''array''name'] [] =「text」似乎只是覆蓋了數組中的第一個條目,同樣的事情發生在'array_push($ array [「name」],「text」)''上。所以我認爲是'JSON.parse()'或'json_encode()'導致它。 –

+0

解決了它,我在xmlHttpRequest中傳遞了一個錯誤, –

0

避免討厭的全局變量和做OOP方式。使用OutputLog類作爲Database類的依賴項。

class OutputLog 
{ 
    protected $log = []; 

    public add($line) { 
     $this->log[] = $line; 
    } 

    public all() { 
     return $this->log; 
    } 
} 

class Database 
{ 
    protected $success; 
    protected $error; 

    public function __construct(OutputLog $success, OutputLog $error) 
    { 
     $this->success = $success; 
     $this->error = $error; 
    } 

    public function login() 
    { 
     // Code 
     $this->error->add('Login Error'); 
     $this->success->add('Login Successful'); 
    } 
} 

$error = new OutputLog(); 
$success = new OutputLog(); 

$db = new Database($success, $error); 
$db->login(); 

$success->add('Main End'); 

echo(json_encode([ $success->all(), $error->all() ])); 
+0

爲什麼globals如此糟糕? '$ output'不接受任何用戶輸入,我在編碼json之後使用'unset($ output)'。我只是很好奇,因爲大家都說他們應該避免。那麼全局變量的正確用法是什麼?另外,你建議的方式正是我想要避免的。我不想在內存中創建'$ output'的太多副本,所以我傳遞了變量的引用,它實際上並不是全局的。我在示例中只使用了該命令。 –

+0

對象默認通過引用傳遞,但給你很大的靈活性。如果你喜歡,你可以在'OutputLog'中使用' - > addSuccess()'和' - > addError()'方法。這種方式更清潔。 –