Using $this when not in object context RethinkDB time object - php

I'm trying to convert an object that holds a rethinkdb datetime object (provided by the PHP-RQL library) but i'm getting a fatal error saying:
Using $this when not in object context
This is an overview of the code:
$day = new stdClass;
$datetime = new DateTime();
$arrival = r\time(
$datetime->format('Y'),
$datetime->format('m'),
$datetime->format('d'),
$datetime->format('H'),
$datetime->format('i'),
$datetime->format('s'),
'Z'
);
$day->arrival = $arrival;
$day = object_to_array($day);
It is in the object_to_array() function I get the fatal error, its code is:
function object_to_array($obj) {
$array = array(); // noisy $array does not exist
$arrObj = is_object($obj) ? get_object_vars($obj) : $obj;
foreach ($arrObj as $key => $val) {
$val = (is_array($val) || is_object($val)) ? $this->getArray($val) : $val;
$array[$key] = $val;
}
return $array;
}
I don't remember where I got this function came from (its not mine) but its served me well in the past.
Essentially my question is why does this object_to_array function fail?
This is what the r\time function returns (an object): https://gist.github.com/fenfe1/6676924
Note: Converting just the time object to an array works fine, but passing an object containing the time fails.
Ultimately I need to end up with an array for use in another function and as other properties will be added to the day object it would be beneficial to keep this as an object.

The error message
Using $this when not in object context
already tells you the reason why the function fails. You use $this. $this is normally used inside a class as a reference to the instantiated object, but in your case you use a simple function, so there is no object context.

Related

Creating default object from empty value- Code igniter

Hello I work on codeigniter and I try to eliminate warnings on my website, I block on:
$groups = array();
if ($bannished_groups) {
foreach ($bannished_groups as $k => $bannished_group) {
$groups[$k] = $this->group_model->GetGroupByID($bannished_group->groupid);
$groups[$k]->db = $bannished_group;
}
}
I have the error:
Creating default object from empty value
I tried to declare:
$groups[$k]->db = new stdClass();
but it does not work and i read the other answers but it does not help me ..
It seems like the method $this->group_model->GetGroupByID($bannished_group->groupid); don't always return an object, even if you think it does :-)
If it returns null, an empty string or false, you will get that error.
Just check it before you try and use it:
foreach ($bannished_groups as $k => $bannished_group) {
// Get the object
$obj = $this->group_model->GetGroupByID($bannished_group->groupid);
if (!is_object($obj)) {
// It's not an object, skip it and move on to the next
continue;
}
$groups[$k] = $obj;
$groups[$k]->db = $bannished_group;
}
This will make sure that your $groups-array only contains objects. If you still want to add it to the array regardless, just store the object directly in $groups[$k] instead of in the $obj-variable. The logic is the same, though.

YAML parse return object not Array using PHP

I want to use a YAML configuration file, for that, I download symfony/yaml package using composer.
I create my test YAML file content:
testing:
test: 2
and to parse it I use this code :
$yaml = Yaml::parse(file_get_contents('test.yml'));
var_dump($yaml->testng);
But, I get this error 'Trying to get property 'testng' of non-object' because the parse return array and I want to get an object.
I tried to add (object) but it works just for the first attribute.
Is there any solution?
According to documentation you should just pass Yaml::PARSE_OBJECT_FOR_MAP as a second parameter of Yaml::parse():
$yaml = Yaml::parse(file_get_contents('test.yml'), Yaml::PARSE_OBJECT_FOR_MAP);
you can use this function
public function toObject($array) {
$obj = new stdClass();
foreach ($array as $key => $val) {
$obj->$key = is_array($val) ? $this->toObject($val) : $val;
}
return $obj;
}

How new object working in the latest version of PHP

As per the PHP 7.2 documentation
A new type, object, has been introduced that can be used for (contravariant) parameter typing and (covariant) return typing of any objects.
And the following example has been given
<?php
function test(object $obj) : object
{
return new SplQueue();
}
test(new StdClass());
Can someone elaborate what is meant by contravariant parameter and covariant return type and how this new object work
object in both places in your code can return generic object i.e an instance of any type. (as shown in your example)
Else it would need to be:
<?php
function test(StdClass $obj) : SplQueue
{
return new SplQueue();
}
test(new StdClass());

When should one pass an object as a parameter vs instantiating?

I am curious about the best practices and any performance or other considerations relating to passing an instance of an object as a parameter to another function in the same class vs creating another instance of that object in the new function. Here's a quick example:
Option 1: Pass both instance of Trainee AND TraineeController to other functions
protected function startTraining($traineeID) {
$traineeController = new TraineeController();
$trainee = $traineeController->findTrainee($traineeID);
$this->initializeTraining($trainee, $traineeController);
$this->doSomeOtherStuffWithTrainee($trainee, $traineeController);
return Redirect::back()->with('trainee', $trainee);
}
protected function initializeTraining($trainee, $traineeController) {
$trainee->blah1 = 'red';
$trainee->blah2 = 'blue';
$propertiesToUpdate = [
'blah1' => $trainee->blah1,
'blah2' => $trainee->blah2
];
$traineeController->updateTrainee($trainee->traineeID, $propertiesToUpdate);
}
Option 2: Pass $trainee ONLY, instantiate a new TaineeController each time
protected function startTraining($traineeID) {
$traineeController = new TraineeController();
$trainee = $traineeController->findTrainee($traineeID);
$this->initializeTraining($trainee);
$this->doSomeOtherStuffWithTrainee($trainee);
return Redirect::back()->with('trainee', $trainee);
}
protected function initializeTraining($trainee) {
$trainee->blah1 = 'red';
$trainee->blah2 = 'blue';
$propertiesToUpdate = [
'blah1' => $trainee->blah1,
'blah2' => $trainee->blah2
];
$traineeController = new TraineeController();
$traineeController->updateTrainee($trainee->traineeID, $propertiesToUpdate);
}
In the above I need to pass $trainee across all functions each time instead of creating a new trainee from $traineeID because some other stuff goes on behind the scenes during the 'training' process that would otherwise be lost before relevant data is saved to the db. However, this is not required for TraineeController - I can either pass it as a parameter or instantiate a new TraineeController as much as I want. Which is the better choice?
I saw this question relating to C#, where the accepted answer was that passing an entire object is usually more efficient and instantiating another one because you are passing by reference. Does this hold true for PHP? Ie is the most efficient approach to pass the entire object by reference to required functions using &?
There is nothing wrong with passing an object as reference, but note that php expects that your function argument needs to expect a reference rather than just passing a variable by reference (php docs). php 5.4.0 will even raise a fatal error if this is not respected:
right:
protected function initializeTraining($trainee, &$traineeController) {}
$this->initializeTraining($trainee, $traineeController);
wrong:
protected function initializeTraining($trainee, $traineeController) {}
$this->initializeTraining($trainee, &$traineeController);
Passing objects by reference will in most cases have better performance than initiating the object again, but passing by reference could become tricky if your object has its own properties:
class TraineeController {
$fooCalled = false;
function foo(){ $this->fooCalled = true; }
function isFooCalled(){ return $this->fooCalled; }
}
$traineeController = new TraineeController();
$traineeController->foo();
//&$traineeController->isFooCalled() will be different from
//new TraineeController()->isFooCalled().

How to make an object resident to a function call?

I have a PHP program I'm writing that does a SOAP request, and it returns an Object. I need to write a function where it takes the data from this Object and uses it in various ways, but I don't want it to do a SOAP request each time if the SOAP request for the data in this Object is already resident.
Pseudo-code example:
$price = GetPartPrice("1234");
function GetPartPrice($part_number) {
If Parts_List_Object not found then do SOAP request to get Parts_List_Object.
}
The problem I see is that I don't know where or how to store if the Parts_List_Object is already there. Do I need to set something up to make the StdClass object that gets requested from the SOAP/JSON request global or is there a better method to do all this? Thanks!
One method would be to build a registry of these objects where you store the ones you fetch and look up the ones you need. That allows you to simply grab a reference to the instance that you've already loaded. A very basic example:
class PartListRegistry {
private static $list = array();
// After you do the SOAP request, call this to save a reference to the object
public static function addPartObject($key, $obj) {
self::$list[$key] = $obj;
}
// Call this to see if the object exists already
public static function getPartObject($key) {
if (isset(self::$list[$key])) {
return self::$list[$key];
}
return null;
}
}
function GetPartPrice($part_number) {
$part = PartListRegistry::getPartObject($part_number);
if ($part === null) {
$part = .... // Do your SOAP request here
// Save a reference to the object when you're done
PartListregistry::addPartObject($part_num, $part);
}
// Do your stuff with the part ....
}

Categories