PHP - can't add objects into array - php

I've created a simple class:
class Event {
var $a;
var $b;
var $c;
function __construct($a, $b, $c)
{
$this->a= $a;
$this->b = $b;
$this->c= $c;
}
}
Then I've created another class which extends Thread:
class WorkerThread extends Thread
{
private $myUrl;
private $eventsArr;
private $counterDebug;
private $postdata;
public function __construct($myUrl, $postdata)
{
$this->myUrl = $myUrl;
$this->postdata = $postdata;
$this->eventsArr = array();
$this->counterDebug=0;
}
public function run()
{
$flag=false;
foreach ($json as $key => $value) {
$this->counterDebug++;
/* Death event */
$event= new Event($a, $b, $c);
array_push($this->eventsArr, $event);
}
}
}
}
echo (count($this->eventsArr));
echo (json_encode($event));
echo ("\n" . $this->counterDebug);
if($flag && count($this->events)>0){
...
When trying to add new created objects into the array, it stays empty.
What I've figured from debugging:
1) The objects are created.
2) neither eventsArr[]= $event, nor array_push are working.
3) I've set a counter that verifies the objects are being created and should be added to the array.
What am I doing wrong?
p.s-
I've removed irrelevant parts of code in order to simplify things.

i think you should create temp array which have all your events and then give it to $eventsArr like this.
$temp = array();
foreach ($json as $key => $value) {
$this->counterDebug++;
/* Death event */
$event= new Event($a, $b, $c);
$temp[] = $event;
}
$this->eventsArr = $temp;
OR
foreach ($json as $key => $value) {
$this->counterDebug++;
/* Death event */
$event= new Event($a, $b, $c);
$this->eventsArr[] = $event;
}

Related

PHP Serialize list of objects to json comming null

I'm trying to pass a list of objects in php to a json but the output is not being as expected.
Controller:
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
require_once "../dao/SubstanciaDAO.php";
require_once "../utils/php/Serialize.php"; // importing util to serialize list of objects
if(array_key_exists("fetchAll",$_GET))
{
$subs = SubstanciaDAO::read(array("all"));//fetching list of objects
if($subs) {
$list = jsonSerializeList($subs);//this function is written bellow in another file
if(isset($list))
echo json_encode($list, JSON_UNESCAPED_UNICODE);//writting output
else
echo "Erro";
}
}
}
Util to serialize list of objects:
First try:
function jsonSerializeList( array $arr ) {
$res = array();
foreach ($arr as $a) {
$aux = get_class_vars(get_class($a));
array_push($res, $aux);
}
return $res;
}
Output:
[[],[],[]]
Second try:
function jsonSerializeList( array $arr ) {
$res = array();
foreach ($arr as $a) {
$aux = get_object_vars($a);
array_push($res, $aux);
}
return $res;
}
Output:
[[],[],[]]
Conclusion
My guess is that there is a problem with the class's private attributes.
In the "$ subs" object list, each position is an object of the "Sustancia.php" class:
class Substancia {
private $id;
private $principioAtivo;
private $nomeComercial;
private $apelidos;
public function __construct() {
$this->apelidos = array();
}
...
Would it be possible to correct the "jsonSerializeList" function so that it works correctly? I really need a function that does this object serialization to use whenever necessary.

Automatically updating a PHP object value based on sum of other object values

Here is a simplified version of the problem.
class A{
public $value = 0;
}
class B{
public $values;
public $total = 0;
function __construct($values) {
foreach($values as $value){
$this->values[] = &$value;
$this->total += $value->value;
}
}
}
$a = new A;
$a->value = 10;
$b = new A;
$b->value = 20;
$x = new B(array($a, $b));
echo $x->total . "\r\n";
$b->value = 40;
echo $x->total;
The output is:
30
30
I want the total to be automatically updated to 50 without iterating on the array and recalculating the sum. Is it possible using PHP pointers?
Desired Output:
30
50
Sums cannot change if there origins change. This information is lost. However you can use the magic __set method to add additional logic to plain setting. There you can call the "calculator" to change the total.
If you do not need to keep the previous interface, you should use a real setter for value (setValue) to achieve this, as __set is not good practice.
For example:
class A
{
private $value = 0;
private $b;
public function setObserver(B $b)
{
$this->b = $b;
}
public function __get($name)
{
if ($name == 'value') {
return $this->value;
}
}
public function __set($name, $value)
{
if ($name == 'value') {
$prev = $this->value;
$this->value = $value;
if ($this->b instanceof B) {
$this->b->change($prev, $this->value);
}
}
}
}
class B
{
public $total = 0;
public function __construct($values)
{
foreach ($values as $v) {
if ($v instanceof A) {
$this->total += $v->value;
$v->setObserver($this);
}
}
}
public function change($prevValue, $newValue)
{
$this->total -= $prevValue;
$this->total += $newValue;
}
}
Prints:
30
50

Update values of all public variables of class using get_object_vars()

I have class with 100 public members. How can I update them in an automated way, ie without specifying their name. I have tried this and I'm getting variables but the changes made doesn't reflect on actual object. Please advice.
class foo {
public $b = 1;
public $c = 2;
function __construct()
{
$x = get_object_vars($this);
foreach ($x as $obj) {
$obj = 9;
}
}
}
$test = new foo;
echo $test->c;
It prints vale of 'c' as 2 instead of 9
function __construct()
{
$x = get_object_vars($this);
foreach ($x as $key => $value) {
$this->$key = 9;
}
}

Sharing array inside object through classes in php

My problem is that I have an object shared through two classes that contains an array inside of it and along the script, someone will request some of the classes the value and a foreach loop will change such value and I want this change to affect every reference of the value.
class bar {
protected $obj;
function __construct(&$obj) {
$this->obj = $obj;
}
public function output() {
print_r($this->obj->value);
}
}
class foo {
protected $obj;
function __construct(&$obj) {
$this->obj = $obj;
}
public function val() {
$result = array();
foreach($this->obj->value as $it){
$result[] = $it;
}
return $result;
}
}
// Shared Object
$obj = new stdClass();
// Default value
$obj->value = array('teste', 'banana', 'maca');
// Class 1
$bar = new bar($obj);
// Class 2
$foo = new foo($obj);
// Someone requests from class 2 the values and changes it
$new = $foo->val();
$new[] = 'abc';
// Class 1 outputs the value
$bar->output(); // this will print the default value. I want this to also have 'abc' value.
The main problem, is that you are building a new array at foo:val, you must return the original object to be modified.
I suggest use ArrayObject, have the same behavior of array but is a object, then always is passed by reference.
<?php
class MyArrayObject extends ArrayObject {
public function replace(Array $array)
{
foreach($this->getArrayCopy() as $key => $value) {
$this->offsetUnset($key);
}
foreach ($array as $key => $value) {
$this[$key] = $value;
}
}
}
class bar {
protected $obj;
function __construct(MyArrayObject $obj) {
$this->obj = $obj;
}
public function output() {
print_r($this->obj);
}
}
class foo {
protected $obj;
function __construct(MyArrayObject $obj) {
$this->obj = $obj;
}
public function val() {
$result = array('foo', 'bar');
$this->obj->replace($result);
return $this->obj;
}
}
// Shared Object
$obj = new MyArrayObject(array('teste', 'banana', 'maca'));
// Class 1
$bar = new bar($obj);
// Class 2
$foo = new foo($obj);
// Someone requests from class 2 the values and changes it
$new = $foo->val();
$new[] = 'abc';
// Class 1 outputs the value
$bar->output(); // this will print the default value. I want this to also
var_dump($obj);

Calling Method of array of objects?

How can I call methods from an array of objects (that hold an array of objects). I read: Get array with results of object method on each item in an array of objects in PHP but could not get it.
Here is my testcode: the first object holds attributes, then an object holds a record of the multiple attributes.
/*--------------------------------- */
class SqliteAttribute {
private $_fieldname = '';
private $_fieldvalue = '';
private $_type = 'TEXT';
private $_key = true;
function __construct($fieldname, $fieldvalue, $text, $key) {
$this->_fieldname = $fieldname;
$this->_fieldvalue = $fieldvalue;
$this->_text = $text;
$this->_key = $key;
}
function AsArray() {
$tempArray = array('fieldname' => $this->_fieldname,
'fieldvalue' => $this->_fieldvalue,
'type' => $this->_type,
'key' => $this->_key
);
return $tempArray;
}
}
/*--------------------------------- */
class SqliteRecord {
private $_attributes = array();
function __construct() {
}
function AddAttribute($fieldname, $fieldvalue, $text, $key) {
$attribute = new SqliteAttribute($fieldname, $fieldvalue, $text, $key);
$this->attributes[] = $attribute;
var_dump($this->_attributes); // shows it!
}
function AsArray() {
$temp_array = array();
var_dump($this->_attributes); // shows nothing
foreach ($this->_attributes as $key => $value) {
$temp_array[] = $value->AsArray();
}
return $temp_array;
}
}
And I call it like this
function updateFiles($files, $rootpath) {
$recordset = new SqliteRecordSet;
foreach ($files as $file) {
$record = new SqliteRecord;
$record->AddAttribute('Path', $file[0], 'TEXT', true);
print_r($record->AsArray()); // shows nothing
}
$recordset->insertIfNotExist_index();
}
$this->attributes vs $this->_attributes
you should always develop code with error reporting set to E_ALL and display_errors on. php would have notified you of your mistake here.

Categories