admin管理员组

文章数量:1317131

I'm having trouble accessing the properties of an object within a Javascript function I created. The object is originally a PHP object which I encoded as JSON using json_encode()

I have 1 PHP file and 1 external JS file.

In my PHP file, I have the ff:

<?php
    $announcementDaoImpl = new AnnouncementDaoImpl($pdo);
    $announcementList = $announcementDaoImpl->getAllAnnouncementByMostRecent();
    foreach($announcementList as $key => $value): ?>
        <tr>
        <td><?php echo $value->getId(); ?></td>
        <td><?php echo $value->getTitle(); ?></td>
        <td><?php echo $value->getDateAdded(); ?></td>
        <?php echo json_encode($value); ?> 
        <td>
        <a href="#" onclick="showEditModal('modalBox',<?php echo json_encode($value); ?>)">Edit</a>
        </td>
        </tr>
    <?php endforeach; ?>

I am able to get and display the values by using the get() methods on the <td>'s. However, when I encode it to JSON via json_encode($value), I get nothing.

Line

<?php echo json_encode($value); ?> 

echoes {} {} {} {} {} {} {} {} {} {} {} {} {} which seems to be empty objects.

My goals are to be able to pass the $value php object to the javascript method showEditModal() then access the object's properties within the method block. Something like, object.propertyname

Below is the javascript method showEditModal() implementation.

function showEditModal(modalDivId,object){
    alert(object.title); //returns undefined

    var modalBox = document.getElementById(modalDivId);
    var modalContentValues = document.getElementById("modalContentValues");
    modalBox.style.display = "block";
    var node = document.createElement("p");
    var text = document.createTextNode(object); //shows [object Object]
    node.style.display = "inline";
    node.appendChild(text);
    modalContentValues.appendChild(node);
}

--- EDIT ---

Here's the class definition.

class Announcement {
    private $id;
    private $title;
    private $content;
    private $dateAdded;


    public function getContent()
    {
        return $this->content;
    }

    public function setContent($content)
    {
        $this->content = $content;
    }

    public function getDateAdded()
    {
        return $this->dateAdded;
    }

    public function setDateAdded($dateAdded)
    {
        $this->dateAdded = $dateAdded;
    }

    public function getId()
    {
        return $this->id;
    }

    public function setId($id)
    {
        $this->id = $id;
    }

    public function getTitle()
    {
        return $this->title;
    }

    public function setTitle($title)
    {
        $this->title = $title;
    }
} 

-- end of edit --

This is what displays on my browser.

I've added some ments to the javascript method for additional details.

I'd appreciate any help.

Thank you.

I'm having trouble accessing the properties of an object within a Javascript function I created. The object is originally a PHP object which I encoded as JSON using json_encode()

I have 1 PHP file and 1 external JS file.

In my PHP file, I have the ff:

<?php
    $announcementDaoImpl = new AnnouncementDaoImpl($pdo);
    $announcementList = $announcementDaoImpl->getAllAnnouncementByMostRecent();
    foreach($announcementList as $key => $value): ?>
        <tr>
        <td><?php echo $value->getId(); ?></td>
        <td><?php echo $value->getTitle(); ?></td>
        <td><?php echo $value->getDateAdded(); ?></td>
        <?php echo json_encode($value); ?> 
        <td>
        <a href="#" onclick="showEditModal('modalBox',<?php echo json_encode($value); ?>)">Edit</a>
        </td>
        </tr>
    <?php endforeach; ?>

I am able to get and display the values by using the get() methods on the <td>'s. However, when I encode it to JSON via json_encode($value), I get nothing.

Line

<?php echo json_encode($value); ?> 

echoes {} {} {} {} {} {} {} {} {} {} {} {} {} which seems to be empty objects.

My goals are to be able to pass the $value php object to the javascript method showEditModal() then access the object's properties within the method block. Something like, object.propertyname

Below is the javascript method showEditModal() implementation.

function showEditModal(modalDivId,object){
    alert(object.title); //returns undefined

    var modalBox = document.getElementById(modalDivId);
    var modalContentValues = document.getElementById("modalContentValues");
    modalBox.style.display = "block";
    var node = document.createElement("p");
    var text = document.createTextNode(object); //shows [object Object]
    node.style.display = "inline";
    node.appendChild(text);
    modalContentValues.appendChild(node);
}

--- EDIT ---

Here's the class definition.

class Announcement {
    private $id;
    private $title;
    private $content;
    private $dateAdded;


    public function getContent()
    {
        return $this->content;
    }

    public function setContent($content)
    {
        $this->content = $content;
    }

    public function getDateAdded()
    {
        return $this->dateAdded;
    }

    public function setDateAdded($dateAdded)
    {
        $this->dateAdded = $dateAdded;
    }

    public function getId()
    {
        return $this->id;
    }

    public function setId($id)
    {
        $this->id = $id;
    }

    public function getTitle()
    {
        return $this->title;
    }

    public function setTitle($title)
    {
        $this->title = $title;
    }
} 

-- end of edit --

This is what displays on my browser.

I've added some ments to the javascript method for additional details.

I'd appreciate any help.

Thank you.

Share Improve this question edited Apr 25, 2018 at 9:14 heisenberg asked Apr 25, 2018 at 8:56 heisenbergheisenberg 1,9644 gold badges39 silver badges75 bronze badges
Add a ment  | 

7 Answers 7

Reset to default 2

You can implement the JsonSerializable interface to define what properties you want to make visible when you serialise an object; e.g:

<?php 

class User implements \JsonSerializable
{
    private $name;

    public function __construct(string $name)
    {
        $this->name = $name;
    }

    public function jsonSerialize()
    {
        return [
            'name' => $this->name,
        ];
    }
}

echo json_encode(new User('Bob')); // {"name":"Bob"} 

This is an idiomatic way to handle object serialisation in PHP in a transparent and implicit manner, and it allows you to define a preferred shape/format for the json respresentation of your object and encapsulate it within its class definition.

It's quite handy when serialising nested object structures, for example, when you were using value objects - here's a (contrived) example:

class Latitude implements \JsonSerializable
{
    private $degree;

    public function __construct(float $degree)
    {
        // validation etc.
        $this->degree = $degree;
    }

    public function jsonSerialize(): float
    {
        return $this->degree;
    }
}

class Longitude implements \JsonSerializable
{
    private $degree;

    public function __construct(float $degree)
    {
        // validation etc.
        $this->degree = $degree;
    }

    public function jsonSerialize(): float
    {
        return $this->degree;
    }
}

class Coordinate implements \JsonSerializable
{
    public function __construct(Latitude $latitude, Longitude $longitude)
    {
        $this->latitude = $latitude;
        $this->longitude = $longitude;
    }

    public function jsonSerialize(): array
    {
        return [
          'latlng' => [$this->latitude, $this->longitude],
        ];
    }
}

$coordinate = new Coordinate(new Latitude(0), new Longitude(0));

echo json_encode($coordinate); // {"latlng":[0,0]} 

Example: https://repl.it/repls/RelievedLightcyanFolders

I'd venture this is because json_encode() scans the public properties of the object and puts those into the results, but in your code you always use getter functions. It's hard to tell without knowing the class definition of the objects you have in $announcementList. Try this:

<?php echo json_encode([
    'id' => $value->getId(),
    'title' => $value->getTitle(),
    'dateAdded' => $value->getDateAdded(),
]); ?>

As seen in your php code, you access the objects attributes via methods. That sounds like the attributes are private. That's why when you are trying to encode the object the result is an empty object.

What you could do:

class MyObject
{
    private $attribute1;
    private $attribute2;

    public function getAttribute1()
    {
        return $this->attribute1;
    }

    public function getAttribute2()
    {
        return $this->attribute2;
    }

    public function toArray()
    {
        return [
            'attribute1' => $this->attribute1,
            'attribute2' => $this->attribute2,
        ];
    }

    public function toJson()
    {
        return json_encode($this->toArray());
    }
}

Now in the php file you can use it like:

<?php
    $announcementDaoImpl = new AnnouncementDaoImpl($pdo);
    $announcementList = $announcementDaoImpl->getAllAnnouncementByMostRecent();
    foreach($announcementList as $key => $value): ?>
        <tr>
        <td><?php echo $value->getAttribute1(); ?></td>
        <td><?php echo $value->getAttribute2(); ?></td>
        <td>
        <a href="#" onclick="showEditModal('modalBox',<?php echo $value->toJson() ?>)">Edit</a>
        </td>
        </tr>
    <?php endforeach; ?>

The problem can be elegantly demonstrated with this simple code:

class Foo {
    private $a = 0;
    protected $b = 1;
    public $c = 2;
}
echo json_encode(new Foo);
// Outputs {"c":2}

Given a standard object, json_encode will only serialize the public properties of the object. If the object you are trying to serialize makes use of private or protected properties, those will not be visible to the JSON encoder; if that's all the object has, you'll get an empty JSON object, like in your case.

If you can alter the class in question, you can implement the JsonSerializable interface to customise the properties to be serialized. If you can't, you will need to build your own representation to pass to JavaScript using the public getter methods, e.g.

echo json_encode([
      'id' => $value->getId(),
      'title' => $value->getTitle(),
      'dateAdded' => $value->getDateAdded()
]);

You're trying to encode an object that contains public methods, but no public properties. json_encode will encode only the public properties.

You can just create an object with real public properties and then serialize it:

<?php
    $announcementDaoImpl = new AnnouncementDaoImpl($pdo);
    $announcementList = $announcementDaoImpl->getAllAnnouncementByMostRecent();
    foreach($announcementList as $key => $value): ?>
        <tr>
        <td><?php echo $value->getId(); ?></td>
        <td><?php echo $value->getTitle(); ?></td>
        <td><?php echo $value->getDateAdded(); ?></td>
        <?php 
             $obj = new stdClass(); 
             $obj->Id = $value->getId();
             $obj->Title= $value->getTitle();
             $obj->DateAdded= $value->getDateAdded();
             var_dump($value);  // just for debugging
             var_dump($obj);    // just for debugging
             echo json_encode($obj); 
        ?> 
        <td>
        <a href="#" onclick="showEditModal('modalBox',<?php echo json_encode($obj); ?>)">Edit</a>
        </td>
        </tr>
    <?php endforeach; ?>

do like like

<a href="#" onclick="showEditModal('modalBox','<?php echo json_encode($value); ?>')">Edit</a>

and inside your function

    function showEditModal(modalDivId,object){
        object = JSON.parse(object) // convert json string to json object
        alert(object.title); //returns undefined

        var modalBox = document.getElementById(modalDivId);
        var modalContentValues = document.getElementById("modalContentValues");
        modalBox.style.display = "block";
        var node = document.createElement("p");
        var text = document.createTextNode(object); //shows [object Object]
        node.style.display = "inline";
        node.appendChild(text);
        modalContentValues.appendChild(node);
    }

You're trying to encode an object that contains public methods, but no public properties. json_encode will encode only the public properties.

A different, elegant and simple approach is using Reflection to create a new object with public properties 'reflecting' your original object private ones:

   <?php
   $announcementDaoImpl = new AnnouncementDaoImpl($pdo);
   $announcementList = $announcementDaoImpl->getAllAnnouncementByMostRecent(); 
   foreach($announcementList as $key => $value): ?>
        <tr>
        <td><?php echo $value->getId(); ?></td>
        <td><?php echo $value->getTitle(); ?></td>
        <td><?php echo $value->getDateAdded(); ?></td>
        <?php
             // gets all PRIVATE properties of $value and stores them to $obj 
             $reflect = new ReflectionClass($value);
             $obj = $reflect->getProperties(ReflectionProperty::IS_PRIVATE);
             
             echo json_encode($obj); 
        ?> 
        <td>
        <a href="#" onclick="showEditModal('modalBox',<?php echo json_encode($obj); ?>)">Edit</a>
        </td>
        </tr>
    <?php endforeach; ?>

本文标签: Passing a PHP Class object to Javascript and accessing its properties in Javascript functionStack Overflow