PHP - Deserialize multiple serialized object from a text file - php

I'm storing objects of a class on a file like this:
if (!empty($_POST)) {
$merenda = new Merenda($_POST["name"], $_POST["numberOfDisp"], $_POST["cost"]);
$merenda = serialize($merenda);
file_put_contents('merende.txt', $merenda, FILE_APPEND);
}
So I'm trying to fetch all objects from another page like this:
$serialized = file_get_contents( "merende.txt" );
$unserialized = unserialize( $serialized );
the content of the serialized file is all in one line, with no break rows
The problem is that the unserialize() function doesn't return an array of objects but only an object passing it a serialized string. I'm looking for a way that I can get an object array from a serialized object file. How could I do it?

You need to save serialized object in a new row in the file.
Then when you need to unserialize objects you need to read the file row by row and unserialize each row.
For example:
<?php
if (!empty($_POST)) {
$merenda = new Merenda($_POST["name"], $_POST["numberOfDisp"], $_POST["cost"]);
$merenda = serialize($merenda) . PHP_EOL;;
file_put_contents('merende.txt', $merenda, FILE_APPEND);
}
<?php
$fileContent = file_get_contents( "merende.txt" );
$objects = [];
foreach (explode(PHP_EOL, $fileContent) as $row) {
$object = unserialize($row);
if ($object) {
$objects[] = $object;
}
}
It is just example to understand the idea, it can be implemented more beautifully.

Related

Concatenate JSON in php with read Database

I read user from the database but I return json to ajax only return the last user because I cant concatenate the json encode.
$myObj = new \stdClass();
while ($fila = $bd->fila()) {
$myObj->NOMBRE = $fila["NOMBRE"];
$myObj->ROLENAME = $fila["ROLENAME"];
$myObj->IDUSER = $fila["IDUSER"];
$myJSON = json_encode($myObj);
}
echo $myJSON;
You are now overwriting $myJson in each iteration. We can also not "concatanate" two jsons (well, we could, but we shouldn't, cause it's laborious..).
Better put everything in one array/object and json_encode() at the very end.
$myObj = new \stdClass();
$users = array(); // instantiate a new array
while ($fila = $bd->fila()) {
$myObj->NOMBRE = $fila["NOMBRE"];
$myObj->ROLENAME = $fila["ROLENAME"];
$myObj->IDUSER = $fila["IDUSER"];
// add objects to that array
$users[] = $myObj;
}
// then at the end encode the whole thing to json:
echo json_encode($users);
Now here are some variants:
If you want everything that your db is returning in this items you could shorten that to:
$users = array(); // instantiate a new array
while ($fila = $bd->fila()) {
// add the whole item (cast as Object) to that array
$users[] = (Object) $fila;
}
// then at the end encode the whole thing to json:
echo json_encode($users);
If you don't care if the items are objects or arrays you could skip the casting and just add the array to the big array:
$users[] = $fila;
Maybe if you concatenate it as array like this
$myJSON[] = $myObj;
and then after the while
echo json_encode($myJSON);
You just have to collect data to big array and then encode whole array. Also there's no reason for creating new StdObjects instead of usual arrays.
// define empty array
$result = [];
while ($fila = $bd->fila()) {
// add to the array all needed elements one by one
$result[] = [
'NOMBRE' => $fila["NOMBRE"],
'ROLENAME' => $fila["ROLENAME"],
'IDUSER' => $fila["IDUSER"],
];
}
// encode whole result
echo json_encode($result);

Removing non-unique JSON object from file using PHP [duplicate]

I need one help.I have some JSON type data and i want to remove the duplicate set of data using PHP.I am explaining my code below.
data=[
{'member_name':member1,'no_of_users':20},
{'member_name':member1,'no_of_users':20},
{'member_name':member1,'no_of_users':20},
{'member_name':member2,'no_of_users':10},
{'member_name':member2,'no_of_users':10},
{'member_name':member3,'no_of_users':30},
]
my php side code is given below.
$res[]=array('member_name'=>$member,'no_of_members'=>$rowno['cnt']);
$result=var_dump( array_unique( $res, SORT_REGULAR ) );
//$result = json_decode($array, TRUE );
print json_encode($result);
Here we can see many duplicate data available.I need to remove only the duplicate data from this JSON object using PHP.Please help me.
First json_decode the JSON string, so we can work with it in PHP. Then you should use array_unique with the flag SORT_REGULAR to remove all duplicates and lastly json_encodeit again to a JSON string. Here's a working example:
$data = '[
{"member_name":"member1","no_of_users":20},
{"member_name":"member1","no_of_users":20},
{"member_name":"member1","no_of_users":20},
{"member_name":"member2","no_of_users":10},
{"member_name":"member2","no_of_users":10},
{"member_name":"member3","no_of_users":30}
]';
// Make a PHP array from the JSON string.
$array = json_decode( $data, TRUE );
// Only keep unique values, by using array_unique with SORT_REGULAR as flag.
// We're using array_values here, to only retrieve the values and not the keys.
// This way json_encode will give us a nicely formatted JSON string later on.
$array = array_values( array_unique( $array, SORT_REGULAR ) );
// Make a JSON string from the array.
$result = json_encode( $array );
Edit:
Based on your edit in your question:
Don't assign $result to a var_dump. Replace $result=var_dump( array_unique( $res, SORT_REGULAR ) ); by $result=array_unique( $res, SORT_REGULAR );
I was faced with the same challenge, so I came up with this simple solution.
<?php
//UniqueValues.php
class UniqueValues{
#The data Array
private $dataArray;
/*
The index you want to get unique values.
It can be the named index or the integer index.
In our case it is "member_name"
*/
private $indexToFilter;
public function __construct($dataArray, $indexToFilter){
$this->dataArray = $dataArray;
$this->indexToFilter = $indexToFilter;
}
private function getUnique(){
foreach($this->dataArray as $key =>$value){
$id[$value[$this->indexToFilter]]=$key;
}
return array_keys(array_flip(array_unique($id,SORT_REGULAR)));
}
public function getFiltered(){
$array = $this->getUnique();
$i=0;
foreach($array as $key =>$value){
$newAr[$i]=$this->dataArray[$value];
$i++;
}
return $newAr;
}
}
?>
include the class in your invocation code and that's all
<?php
//index.php
include_once('UniqueValues.php');
#Your JSON data
$data = '[
{"member_name":"member1","no_of_users":20},
{"member_name":"member1","no_of_users":20},
{"member_name":"member1","no_of_users":20},
{"member_name":"member2","no_of_users":10},
{"member_name":"member2","no_of_users":10},
{"member_name":"member3","no_of_users":30}
]';
#Convert your JSON to Array
$array = json_decode( $data, TRUE );
/*
Create an object by passing the "Two Dimension Array" in this case "$array" and
the "index" in this case "member_name" that you want to get the Unique Values
*/
$supper = new UniqueValues($array,"member_name");
/*
Get the unique valued array by calling the getFiltered() function
and encode it to JSON
*/
$result = json_encode( $supper->getFiltered() );
#Let the World See it :)
echo $result;
?>
Here, how can I solve this. See with example. make json unique
code part:
<?php
$depositeArray = array( 'deposite'=>array(
array('email'=>"sajib#gmail.com", 'deposite'=>0),
array('email'=>"avi#gmail.com", 'deposite'=>0),
array('email'=>"iqbal#gmail.com", 'deposite'=>0),
array('email'=>"balla#gmail.com", 'deposite'=>0),
array('email'=>"sajib#gmail.com", 'deposite'=>0),
array('email'=>"razib#gmail.com", 'deposite'=>0)
),
'total'=>0);
$depositeArray = json_encode($depositeArray);
$depositeArray = json_decode($depositeArray,true);
$depositeArrayNew = Json_Super_Unique($depositeArray['deposite'],'email');
$depositeArray['deposite'] = $depositeArrayNew ;
echo json_encode($depositeArray);
function Json_Super_Unique($array,$key){
$temp_array = array();
foreach ($array as &$v) {
if (!isset($temp_array[$v[$key]]))
$temp_array[$v[$key]] =& $v;
}
$array = array_values($temp_array);
return $array;
}
?>

How to edit JSON objects

I'm on PHP and I need to edit a JSON output to return only objects >=0 and divided by one hundred
Eg.
$json = {"data":[0,55,78,-32,-46,37]}
Needed
$json = {"data":[0,0.55,0.78,0.37]}
How this can be done?
Well, I know this is not the best practice, but if it's as simple as this, you can do the following.
$json = '{"data":[0,55,78,-32,-46,37]}';
// decoding the string to objects & arrays
$x = json_decode($json);
// applying a function on each value of the array
$x->data = array_map(
function($a)
{
if( $a >= 0 ) return $a/100;
else return null;
},
$x->data
);
// Removing empty values of the array
$x->data = array_filter($x->data);
// making a JSON array
$jsonData = json_encode(array_values($x->data));
// inserting a JSON array in a JSON Object
$json = '{"data":' . $jsonData . '}';
// here is your {"data":[0,0.55,0.78,0.37]}
echo $json;
Hope it helps !
Btw, I had to trick the json encode with array_values to prevent the creation of an object rather than an array for the data content. But I guess there is a better method that I just don't know ...
EDIT :
Find out the way :D
Once empty values removed from the array, just do :
$x->data = array_values($x->data);
$json = json_encode($x);
This will do the trick and it will not create issues with the rest of the object.
Alessandro:
Here's my approach, feel free to try. json_decode and a simple foreach can help you...
Code:
$json = array();
$result = array();
$json = '{"data":[0,55,78,-32,-46,37]}';
$decoded_json=json_decode($json, TRUE);
foreach ($decoded_json['data'] as &$value) {
if ($value >= 0){
$value = $value / 100;
$result[]=$value;
}
}
echo json_encode($result);
?>
Result:
[0,
0.55,
0.78,
0.37
]

Retrieve all values in my loop and format it to json

I'm trying to build a page which queries my database and then formats output so another webservice/page can access the data.
Ideally I wanted to explore having the data in JSON format, but that is not working. The other problem I have which is more major than the JSON not working is, if I have 3 records in $reportsResult, only the last one is displayed.
Anyone with some help please. Oh do I also need to print_r for the external webpage to retrieve the data or is there a better way?
class Pupil {
public $FirstName = "";
public $LastName = "";
}
foreach($reportsResult->getRecords() as $reportRecord) {
$Pupil = new Pupil();
$Pupil->FirstName = $reportRecord->getField('FName');
$Pupil->LastName = $reportRecord->getField('SName');
}
json_encode($Pupil);
OK managed to figure out how how to get all records from the loop, but its still not displaying in json format when I do a print_r - am I missing something?
$AllPupils = array();
foreach($reportsResult->getRecords() as $reportRecord)
{
$Pupil = new Pupil();
$Pupil->FamID = $reportRecord->getField('FName');
$Pupil->ChildName = $reportRecord->getField('SName');
array_push($AllPupils, $Pupil);
}
json_encode($AllPupils);
Everytime your foreach loop starts again, it will override your $Pupil variable.
Try an array instead:
$Pupil = array()
$i = 0;
foreach($reportsResult->getRecords() as $reportRecord) {
$Pupil[$i] = new Pupil();
$Pupil[$i]->FirstName = $reportRecord->getField('FName');
$Pupil[$i]->LastName = $reportRecord->getField('SName');
$i++;
}
echo json_encode($Pupil);
Edit: mikemackintosh's solution should also work and could be a little bit faster (depending on the size of your foreach loop).
To display the results you need to echo your data (not only json_encode).
You will probably run into issues since json_encode wont handle the whole object. for that, you may want to serialize the $Pupil object.
Something like below may work for you though. It will assign the values to a returned array, which will allow json_encode to execute gracefully:
class Pupil {
public $FirstName = "";
public $LastName = "";
public function getAttr(){
return array("FirstName" => $this->FirstName, "LastName" => $this->LastName);
}
}
$json = array();
foreach($reportsResult->getRecords() as $reportRecord) {
$Pupil = new Pupil();
$Pupil->FirstName = $reportRecord->getField('FName');
$Pupil->LastName = $reportRecord->getField('SName');
$json[] = $Pupil->getAttr();
}
echo json_encode($json);
I am not sure why you have that class defined, but you know what in your for each have something like
foreach ($reportsResult->getRecords() as $key => $record) {
$data[$key]['firstname'] = $record->getField('Fname');
$data[$key]['lastname'] = $record->getField('Sname');
}
And then you can check the final array using print_r
and while output you can simply do a print json_encode($data) and it will give you a json string of all the items in the data array.
In php (at least), json_encode takes an array as parameter.
Therefore you should add a constructor to your class
function __construct($first, $last)
{
this.$FirstName = $first;
this.$LastName = $last;
}
and one for getting the full name as an array, ready to be jsoned
function getNameArray()
{
$nameArray = array();
$nameArray['firstName'] = this.$FirstName;
$nameArray['lastName'] = this.$LastName;
return $nameArray;
}
then in that foreach you build another array with all the pupils
$pupils = array();
foreach (bla bla)
{
$first = $reportRecord->getField('FName');
$last = $reportRecord->getField('SName');
$Pupil = new Pupil($first, $last);
array_push($pupils, $pupil.getNameArray());
}
finally, you have everything preped up
json_encode($pupils);
I'm sure there's other ways to debug your stuff, I use print_r mainly also.

building an associative array

This is going to be my first time building an associative array. And if anyone can help me I would be grateful.
Basically, I want to loop through a directory of XML files. I want to find out if a certain editor was the editor of this file, and if the query is true, I would like to grab two pieces of information and achieve the result of an associate array with those two pieces of information for every case where the editor's name is found.
So here's what I have got so far:
function getTitleandID($editorName) {
$listofTitlesandIDs = array();
$filename = readDirectory('../editedtranscriptions');
foreach($filename as $file)
{
$xmldoc = simplexml_load_file("../editedtranscriptions/$file");
$xmldoc->registerXPathNamespace("tei", "http://www.tei-c.org/ns/1.0");
if ($editorName == $xmldoc->xpath("//tei:editor[#role='PeerReviewEditor']/text()"))
{
$title = $xmldoc->xpath("//tei:teiHeader/tei:title[1]");
$id = $xmldoc->xpath("//tei:text/tei:body/tei:div/#xml:id[1]");
$listofTitlesandIDs[] = //I don't know what to do here
}
else
{
$listofTitlesandIDs = null;
}
}
return $listofTitlesandIDs
}
This is about where I get stuck. I'd like to be able have $listofTitlesandIDs as an associative array where I could call up the values for two different keys, e.g. $listofTitlesandIDs['title'] and $listofTitlesandIDs[$id]
So that's about it. I'm grateful for any help you have time to provide.
Well I'm sure this is a little clumsy (the result of an amateur) but it has given me the result I want.
function getTitlesandIDs($EditorName) //gets titles and IDs for given author
{
$list = array();
$filename = readDirectory('../editedtranscriptions');
foreach($filename as $file)
{
$xmldoc = simplexml_load_file("../editedtranscriptions/$file");
$xmldoc->registerXPathNamespace("tei", "http://www.tei-c.org/ns/1.0");
$title = $xmldoc->xpath("//tei:teiHeader/tei:fileDesc/tei:titleStmt/tei:title[1]");
$id = $xmldoc->xpath("//tei:text/tei:body/tei:div/#xml:id");
$editorName = $xmldoc->xpath("//tei:editor[#role='PeerReviewEditor']/text()")
if ($editorName[0] == "$EditorName")
{
$result = array("title"=>$title[0], "id"=>$id[0]);
$list[] = $result;
}
}
return $list;
}
With this I can call the function $list = getTitlesandIDs('John Doe') and then access both the title and id in the associative array for each instance. Like so:
foreach ($list as $instance)
{
echo $instance['title'];
echo $instance['id'];
}
Maybe that will help somebody some day -- let me know if you have any advice on making this more elegant.
$listofTitlesandIDs[$id] = $title;
You should loop over the array then using the foreach loop.

Categories