How do I convert from my PHP array (mysql_fetch_array) to a declared PHP Class then encode that to json format string. My array:
while ($rows = mysql_fetch_array($result, MYSQL_ASSOC)){
$patient[] = array( 'id' => $rows['id'],
'name' => $rows['name'],
'sex' => $rows['sex'],
'civil_status' => $rows['civil_status'],
'age' => $rows['age'],
'type_of_admission' => $rows['type_of_admission'],
'admission_diagnosis' => $rows['admission_diagnosis'],
'date_admitted' => $rows['date_admitted']);
}
My declare PHP Class
class Person
{
public $id;
public $name;
public $sex;
public $civil_status;
public $age;
public $type_of_admission;
public $admission_diagnosis;
public $date_admitted;
}
I think you are looking for mysql_fetch_object:
while ($row = mysql_fetch_object($result, 'Person')){
$json_rows[] = json_encode($row);
}
Also, you should be using mysqli, which has the same basic concept.
just retype to (object)
$object = (object) $array_name;
for json_encode.
Related
I know this question is more data structures but since I am doing it in Symfony there might be a simpler way. I have a recursive function treeBuilder() I want to call on some data to create a hierarchy. Say a database of people and I want to create a tree structure if they live with their parents. I know I am passing an array of object to the function but it needs to be an array. I am pretty sure I need to rewrite this function so that it handles the the array of object but am stumped. I am not sure how to access the elements of the array to check the parentid. I know the code below is not correct but that is where I am at now.
Controller:
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('CompanyMyBundle:Org')->findAll();
var_dump($entities);
$tree=$this->treeBuilder($entities);
return array(
'entities' => $tree,
);
}
private function treeBuilder($ar, $pid=null)
{
$op=array();
foreach( $ar as $item ) {
// I know I have an array of objects
if( $item['ParentId'] == $pid ) {
$op[$item['Id']] = array(
'Street' => $item['Street'],
'ParentId' => $item['ParentId']
);
$children = self::treeBuilder( $ar, $item['Id'] );
if( $children ) {
$op[$item['Id']]['children'] = $children;
}
}
}
return $op;
}
var_dump($entities) from indexAction():
/export/www/working/symfony/src/Company/MyBundle/Controller/DepController.php:34:
array (size=60)
0 =>
object(Company\MyBundle\Entity\Org)[1556]
private 'Name' => string 'Me' (length=46)
private 'Street' => string '123 Sesame' (length=255)
private 'City' => string 'Myhometown' (length=255)
private 'ParentId' => int 0
private 'Id' => int 1
1 =>
object(Company\MyBundle\Entity\Org)[1557]
private 'Name' => string 'Me2' (length=46)
private 'Street' => string '123 Sesame' (length=255)
private 'City' => string 'Myhometown' (length=255)
private 'ParentId' => int 1
private 'Id' => int 2
If you need to get entities as arrays instead of objects, you would need to use Doctrine's hydrator:
$em = $this->getDoctrine()->getManager();
$orgRepo = $em->getRepository('CompanyMyBundle:Org');
$entities = $orgRepo->createQueryBuilder('org')
->getQuery()
->getResult(\Doctrine\ORM\AbstractQuery::HYDRATE_ARRAY);
Note:
I would suggest to leave entities as objects and use getters:
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('CompanyMyBundle:Org')->findAll();
$tree = $this->treeBuilder($entities);
return array(
'entities' => $tree,
);
}
private function treeBuilder($entities, $pid = null)
{
$op = array();
/** Org $entity */ //Type hinting, if you use autocompletion
foreach ($entities as $entity) {
if ($entity->getParentId() == $pid) {
$op[$entity->getId()] = [
'Street' => $entity->getStreet(),
'ParentId' => $entity->getParentId()
];
$children = self::treeBuilder($entities, $entity->getId());
if (!empty($children)) {
$op[$entity->geId()]['children'] = $children;
}
}
}
return $op;
}
i'm trying to refresh my memory of OO & array structure. i have,
class room{
private $people = array(
'name' => array(
'height' => null,
'age' => null
)
);
function set($list){
foreach($list as $person){
$this->people[$person['name']]['height'] = $person['height'];
$this->people[$person['name']]['age'] = $person['age'];
}
}
function print(){
foreach($this->people as $k => $v){
echo $k . "<br>";
echo $v['height'] . ":" . $v['age'] . "<br><br>";
}
}
}
$input = array( array('name' => 'John', 'height' => '6.4', 'age' => '20'),
array('name' => 'Jane', 'height' => '5.2', 'age' => '21')
);
$i = new room;
$i->set($input);
$i->print();
the output is,
name
:
John
6.4:20
Jane
5.2:21
i'm confused as why name : appears first, when the input array only contains 2 values of each person. i am unsure if i am using my arrays correctly, could someone point out my mistake?
My overall aim of this is to have correct understanding of arrays within arrays & how to best set & get the values
It's because you've initialised the $people array to contain those values
private $people = array(
'name' => array(
'height' => null,
'age' => null
)
);
Change it to:
private $people = array();
that's the good way to do it
your people class
class people {
//properties
private $name;
private $height;
private $age;
//setters
public function setName($name) {
$this->name = $name;
}
public function setHeight($height) {
$this->height = $height;
}
public function setAge($age) {
$this->age = $age;
}
//getters
public function getName() {
return $this->name;
}
public function getHeight() {
return $this->height;
}
public function getAge() {
return $this->age;
}
}
your room class
class room {
//properties
private $people = array();
//setters
public function setPeople($people) {
$this->people[] = $people;
}
//getters
public function getPeoples() {
return $this->people;
}
}
and how to control it in OOP
$people1 = new people();
$people1->setName('John');
$people1->setHeight('6.4');
$people1->setAge('20');
$people2 = new people();
$people2->setName('Jane');
$people2->setHeight('5.2');
$people2->setAge('21');
$room = new room();
$room->setPeople($people1);
$room->setPeople($people2);
// Removing people array initial data will solve the issue :)
class room{
private $people = array();
function set($list){
foreach($list as $person){
$this->people[$person['name']]['height'] = $person['height'];
$this->people[$person['name']]['age'] = $person['age'];
}
}
function print(){
foreach($this->people as $k => $v){
echo $k . "<br>";
echo $v['height'] . ":" . $v['age'] . "<br><br>";
}
}
}
$input = array( array('name' => 'John', 'height' => '6.4', 'age' => '20'),
array('name' => 'Jane', 'height' => '5.2', 'age' => '21')
);
$i = new room;
$i->set($input);
$i->print();
I have a PHP class I would like to transform in a JSON on several levels like this type:
{"interface":{"Version":"0"},"Container":[{"id":"1","Element":[{"text":"Test","id":"0"},{"text":"Toto","id":"1"}]}]}
In my PHP class I have a function who returns the JSON of my private attributes who are arrays:
return (json_encode((get_object_vars($this)), JSON_UNESCAPED_UNICODE));
Private attributes of my class:
private $interface = '';
private $Container = array(array('id' => '1'));
private $Element = array('text' => 'Test', 'id' => '0');
Do you know how I could have a JSON like above ?
In pleasure to read you.
Not sure about your class members but as long as they are accessible you can generate the JSON string. Below if the example of this
$Contenant = array(array('id' => '1'));
$Element = array('text' => 'Test', 'id' => '0');
$json = json_encode(array('inerrface'=>array(
'content'=>$Contenant,
"Element"=>$Element
)
)
);
echo $json ;
You could implement the IteratorAggregate interface like in the following example
class YourClass implements IteratorAggregate {
protected $member1 = array();
protected $member2 = array();
...
public function getIterator() {
$tmpArr = array();
// create the structure you want in $tmpArr
return new ArrayIterator($tmpArr);
}
}
$myClass = new MyClass();
$iterator = $myClass->getIterator();
$encodedData = json_encode($iterator);
As of PHP5.4 you have the JsonSerializable interface ready to use. With this interface, you cann use direct modifications like in the example given in: http://de2.php.net/manual/en/jsonserializable.jsonserialize.php
have fun! ;)
This will get you started, take a look at the constructor what data input requires. You could make a private function doing the same thing, assigning your values to the structure and then printing it:
class Test{
private $data;
public function __construct($version = 0, $records = array()){
$data['interface'] = array('Version' => $version);
$data['Container'] = array();
for ($i = 0; $i < count($records); $i++) {
$data['Container'][$i] = $records[$i];
}
// your test input
print_r(json_decode('{"interface":{"Version":"0"},"Container":[{"id":"1","Element":[{"text":"Test","id":"0"},{"text":"Toto","id":"1"}]}]}',true));
// actual input
print_r($data);
// printing our actual data as json string
echo json_encode($data);
}
public function __destruct(){
}
}
$element1 = array('text' => 'Test', 'id' => 0);
$element2 = array('text' => 'Toto', 'id' => 1);
$elements = array($element1, $element2);
$record = array('id' => 1, 'element' => $elements);
$records = array($record);
new Test(0, $records);
You need to structure it, working example: example
class test {
private $interface = '';
private $Contenant = array(array('id' => '1'));
//private $Element = array(array('text' => 'Test', 'id' => '0'));
public function json(){
$this->Contenant = array(
array('id' => '1',
'Element' => array(array('text' => 'Test', 'id' => '0'))
),
);
return json_encode((get_object_vars($this)), JSON_UNESCAPED_UNICODE);
}
}
$t = new test();
$encode = $t->json();
echo $encode;
OUTPUT
{"interface":"","Contenant":[{"id":"1","Element":[{"text":"Test","id":"0"}]}]}
I have an associative array like this
$imagePaths = array(
'logo' => "logo.jpg",
'facebook-logo' => "facebook-icon.jpg",
'twitter-logo' => "twitter-icon.jpg",
'linkedin' => "linkedIn.jpg"
);
for me to call logo, I use below code
$ClassInstance->imagePaths['logo'];
But I would also like to be able to call it using
$ClassInstance->imagePaths[0];
Is there anyway to do this?
You can achieve this with array_keys():
$keys = array_keys($imagePaths);
$ClassInstance->imagePaths[$keys[0]];
You could store a second array using array_values():
$imagePathsKeyed = array_values($imagePaths);
EDIT: I've expanded the example code to help here
<?php
class SomeObject
{
public $imagePaths;
public $keyedImagePaths;
public function __construct()
{
$this->imagePaths = array(
'logo' => "logo.jpg",
'facebook-logo' => "facebook-icon.jpg",
'twitter-logo' => "twitter-icon.jpg",
'linkedin' => "linkedIn.jpg"
);
$this->keyedImagePaths = array_values($this->imagePaths);
}
}
$classInstance = new SomeObject();
// logo.jpg
echo $classInstance->imagePaths['logo'];
// logo.jpg
echo $classInstance->keyedImagePaths[0];
Given that you have an array that contains varying amounts of objects, how can you access the properties of the last object? I tried to use end($array); but it gives the error: Object of class Post could not be converted to string
The class is:
class Post {
private $datafile;
public $index;
public $subIndex;
public $poster;
public $title;
public $message;
public $date;
// constructor and some unrelated methods here
public function getCommentData($givenIndex) {
$comments = null;
$data = file($this->datafile);
foreach($data as $row) {
list($index, $subIndex, $poster, $message, $date) = explode('|', $row);
$this->index = $subIndex; // SubIndex ties a Comment to a Post (same ID)
if($this->index == $givenIndex) {
$comment = new Post();
$comment->poster = $poster;
$comment->message = $message;
$comment->date = date(DATEFORMAT, strtotime($date));
$comments[] = $comment;
}
}
return $comments;
}
}
Now, I would like to access only the last Comment item's properties, but I'm not sure how it should be done? In a regular array, end() is quick and easy to use, but how about with objects as it doesn't seem to work?
Here is an example var_dump:
array (size=2)
0 =>
object(Post)[4]
private 'datafile' => null
public 'index' => null
public 'subIndex' => null
public 'poster' => string 'Postaaja' (length=8)
public 'title' => null
public 'message' => string 'Kommentti' (length=9)
public 'date' => string '5 Mar 2013 | 23:12' (length=18)
1 =>
object(Post)[5]
private 'datafile' => null
public 'index' => null
public 'subIndex' => null
public 'poster' => string 'Toinenkin' (length=9)
public 'title' => null
public 'message' => string 'Lisäkommentti' (length=14)
public 'date' => string '5 Mar 2013 | 23:13' (length=18)
Thanks!
EDIT:
Here's the way I tried to use it:
$comments = new Post(FILECOMMENTS);
$currentComments = $comments->getCommentData($i); // $i is the index of current newspost item
$newsComments = new Format();
$newsComments->formatShortComment($currentComments, $i);
And the method in the Format class:
// This comment is displayed as a short text in the main News view
public function formatShortComment($data, $index) {?>
<div class="newsComments">
<p class="newsPreviewComment">
<?php
$lastItem = end($data);
if(!empty($lastItem->message)) {
echo '<i>"',$lastItem->message,'"</i> ';
echo '-',$lastItem->poster;
}
?></p>
» Show All/Add comments
(<?php echo $commentCount; ?>)
</div><?php
}
You could try:
$tempArray = array_values($data);
$lastItem = $tempArray[count($tempArray)-1];
I hope I didn't miss something important, but if you're just trying to get the last element of a PHP array:
$lastItem = $data[count($data) - 1];