PHP通过引用

时间:2017-02-15 00:06:43

标签: javascript php arrays json

我试图在php中构建一个JSON服务器响应。当服务器运行脚本时,我在输出中使用一个数组来跟踪脚本中的错误和成功。如下面的代码所示。

<?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" : []
}

问题似乎是当我尝试通过引用传递$ output的数据库类的单例实例或调用json_encode()时。我已经查看了全部,这是通过引用传递的唯一方法,但有趣的是,如果数据库中的错误JSON.parse()在javascript中引发错误,并且输出isn&#39; php错误日志。无论如何,通过传递$output的引用来了解这一点,因为有时我会期望$ output变得非常大并且我希望将数组的副本保持在最低限度而且我真的不是如果我做了类似这样的事情,那么php数组函数还是很好的。     $ output [&#34; error&#34;] [] = $ db-&gt; 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 - &gt;起点

<?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 - &gt;数据库类

<?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");

        ...
    }
}

感谢帮助向导和Chris。 =)

2 个答案:

答案 0 :(得分:0)

尝试将其设置为:

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

但是全局变量是邪恶的:)

答案 1 :(得分: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() ] ) );