如何将大型PHP对象转换为JSON

时间:2018-10-05 11:39:09

标签: php json

我正在使用CodeIgniter,我想将电子邮件的表示形式存储在数据库中(由发送这些电子邮件的CRON作业提取)。因为我们意识到一次发送的电子邮件太多,导致根本没有发送一些电子邮件。因此,我们希望在数据库正确发送时进行跟踪。

我的数据库表包含以下列:

CREATE TABLE `mail_queue`(
    `mail_id` INT(11) NOT NULL AUTO_INCREMENT, 
    `from` VARCHAR(255) NOT NULL,
    `to` VARCHAR(255) NOT NULL,
    `mail_object` JSON NOT NULL,
    `date_inserted` datetime DEFAULT CURRENT_TIMESTAMP,
    `priority` INT(11) NOT NULL,
    `mail_sent` INT(11) NOT NULL DEFAULT '0',
    INDEX `mail_queue_FI_1` (`priority`),
    INDEX `mail_queue_FI_2` (`mail_sent`),
    PRIMARY KEY (`mail_id`)
) ENGINE = InnoDB;

下面的PHP代码显示了如何创建电子邮件:

//Initialize mail
        $this->load->library('email');

        $config['protocol'] = 'smtp';
        $config['smtp_host'] = 'smtp.office365.com';
        $config['smtp_user'] = GENERAL_MAIL;
        $config['smtp_pass'] = GENERAL_MAIL_PW;
        $config['smtp_port'] = '587';
        $config['charset']='utf-8';
        $config['newline']="\r\n";
        $config['crlf'] = "\r\n";
        $config['smtp_crypto'] = 'tls';
        $config['mailtype'] = 'html';
        $this->email->initialize($config);

        $this->email->from(GENERAL_MAIL, 'me');
        $this->email->to('dennis@me.com');
        $this->email->subject("test123cron");
        $message = $this->load->view('mail/membership/request',"123",TRUE);
        $this->email->message($message);

对象$ this-> email然后包含一个PHP对象,该对象内部包含很多参数。有些是公开的,有些是受保护的。

例如:

...
  public 'bcc_batch_mode' => boolean false
  public 'bcc_batch_size' => int 200
  protected '_safe_mode' => boolean false
  protected '_subject' => string '' (length=0)
  protected '_body' => string '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="format-detection" content="telephone=no" /> <!-- disable auto telephone linking in iOS -->
    <title> <title>Geregistr'... (length=49335)
  protected '_finalbody' => string '' (length=0)
...

通过使用json_encode,似乎只有公共参数以JSON编码,而受保护的则不是。

我已经阅读了有关实现JsonSerialization的信息,但是根据文档“指定应序列化为JSON的数据”。我是否需要在其中定义每个对象参数?我什至不确定每次是否都是固定金额。

编辑: 我尝试了评论提供的建议,我的代码如下:

class Cron extends MY_Controller implements JsonSerializable
{
    public function __construct()
    {
        parent::__construct();
        // Force SSL
        $this->force_ssl();

        //Initialize mail
        $this->load->library('email');

        $config['protocol'] = 'smtp';
        $config['smtp_host'] = 'smtp.office365.com';
        $config['smtp_user'] = GENERAL_MAIL;
        $config['smtp_pass'] = GENERAL_MAIL_PW;
        $config['smtp_port'] = '587';
        $config['charset']='utf-8';
        $config['newline']="\r\n";
        $config['crlf'] = "\r\n";
        $config['smtp_crypto'] = 'tls';
        $config['mailtype'] = 'html';
        $this->email->initialize($config);
    }
    public function sendQueuingMails() {

        $this->email->from(GENERAL_MAIL, 'me');
        $this->email->to('dennis@me.com');
        $this->email->subject("test123cron");
        $message = $this->load->view('mail/membership/request',"123",TRUE);
        $this->email->message($message);

        var_dump($this->email);

        $jsonencode = json_encode($this->email);
        var_dump($jsonencode);

        $jsondecode = json_decode($jsonencode);
        var_dump($jsondecode);
    }

    public function jsonSerialize()
    {
        return get_object_vars($this);
    }
}

编码的JSON对象的输出为:

D:\wamp\www\codeigniter\application\controllers\cli\Cron.php:594:string '{"useragent":"CodeIgniter","mailpath":"\/usr\/sbin\/sendmail","protocol":"smtp","smtp_host":"smtp.office365.com","smtp_user":"dev@giveaday.be","smtp_pass":"266duZg6x4TP66Vn","smtp_port":"587","smtp_timeout":5,"smtp_keepalive":false,"smtp_crypto":"tls","wordwrap":true,"wrapchars":76,"mailtype":"html","charset":"utf-8","multipart":"mixed","alt_message":"","validate":false,"priority":3,"newline":"\r\n","crlf":"\r\n","dsn":false,"send_multipart":true,"bcc_batch_mode":false,"bcc_batch_size":200}' (length=495)

这表明它没有对受保护的属性进行编码。

编辑2: 根据下面链接的博客文章,我将jsonSerialize方法的代码更改为以下代码:

public function jsonSerialize()
        {
            $json = array();
            foreach($this as $key => $value) {
                $json[$key] = $value;
            }
            return $json;
        }

结果是相同的。我注意到jsonSerialize方法只是没有被调用。无论我放在那里,例如返回“ testtest”;似乎继续从其他地方使用json_encode?

1 个答案:

答案 0 :(得分:0)

您确定JsonSerializeable无效吗?

class Cron implements \JsonSerializable
{
  protected $test1;
  private $test2;
  public function __construct()
  {
    $this->test1 = 'protected';
    $this->test2 = 'private';
  }


  public function jsonSerialize()
  {
    return get_object_vars($this);
  }
}

$cron = new Cron;

print_r(json_encode($cron->jsonSerialize()));

打印

{"test1":"protected","test2":"private"}