Attempt to assign property of non-object error - php

I am getting this error and i can't see what i am doing wrong. I have done the same thing with other objects from other classes which are built in the exact same way and i can't see why i am getting this error now.
The code in which i create the object is this one:
$consulta2 = "SELECT * FROM TiposDireccion WHERE Cliente_CIF='$cif' and Direccion_Direccion='$direccion' and Direccion_CP=$cp ";
echo($consulta2."</br>");
if ($resultado2 = $conexion->query($consulta2)){
while($fila2 = $resultado2->fetch_object()){
$tipodireccion78=$fila2->TipoDireccion_Tipo;
//we see here that the select is returning a correct string with a correct value
echo($tipodireccion78);
//we try to instantiate and it fails =(
$unTipoDireccion=TipoDireccion::constructor1($tipodireccion78);
This is the class TipoDireccion:
<?php
class TipoDireccion{
private $tipo;
private $descripcion;
//Construct auxiliar
function __construct() {
}
//Constructor 1 : completo
function constructor1($tipo) {
$tipoDireccion = new TipoDireccion();
$tipoDireccion->tipo = $tipo;
return $tipoDireccion;
}
function ponTipo($tipo) {
$this->tipo = $tipo;
}
function devuelveTipo() {
return $this->tipo;
}
function ponDescripcion($descripcion) {
$this->descripcion = $descripcion;
}
function devuelveDescripcion() {
return $this->descripcion;
}
}
?>
Thank you a lot in advance!

Don't know if this is still relevant to you, but in case anyone else comes on here for an answer. The problem is in this function:
function constructor1($tipo) {
$tipoDireccion = new TipoDireccion();
$tipoDireccion->tipo = $tipo;
return $tipoDireccion;
}
Because in the class definition, you define private $tipo; and then you try and assign $tipoDireccion->tipo to what was passed through the function. However, you aren't trying to access that variable through the scope of the class, you are trying to assign it from the 'public' scope as far as the class is concerned.
The fix for this has two options, the first one would be to change private $tipo; to public $tipo;. But that isn't a good solution as you have an assignment function for it.
Instead, use your functions that you made, which would make the function look like:
function constructor1($tipo) {
$tipoDireccion = new TipoDireccion();
$tipoDireccion->ponTipo($tipo);
return $tipoDireccion;
}
That's how you need to access it from the public scope, which you are doing after you initiate a new one.

function constructor1($tipo) {}
should be
static function constructor1($tipo) {}

Related

Access PHP object from inside a function

I have created a PHP class and I want to access its methods from a function in another file. Below is my code:
include_once PLUGIN_DIR_PATH."/classes/Brands.php";
function create_tables(){
$brand_obj = new Brands;
$brand_obj->create_brand_table();
}
function delete_tables() {
$brand_obj = new Brands;
$brand_obj->delete_brand_table();
}
Is it possible to create the object only once and then reuse it in every function? Right now, I am creating object in every function which is not a good practice.
You can use the global keyword to use a variable created outside a function inside a function:
global $object
code example :
include_once PLUGIN_DIR_PATH."/classes/Brands.php";
$brand_obj = new Brands;
function create_tables(){
global $brand_obj;
$brand_obj->create_brand_table();
}
function delete_tables() {
global $brand_obj;
$brand_obj->delete_brand_table();
}
I'm going to assume your actual functions do more than what you posted, otherwise you don't really need functions and can simply do this:
$brand_obj = new Brands;
$brand_obj->create_brand_table();
$brand_obj->delete_brand_table();
Otherwise, you can make a class and inject the Brands dependency into one of its properties via its constructor:
class TablesManager
{
private $brands;
public function __construct(Brands $brands)
{
$this->brands = $brands;
}
public function create_tables(): void
{
$this->brands->create_brand_table();
}
public function delete_tables(): void
{
$this->brands->delete_brand_table();
}
}
Usage:
$brands = new Brands();
$tables_manager = new TablesManager($brands);
$tables_manager->create_tables();
$tables_manager->delete_tables();
Note: calling a class SomethingManager is sometimes considered bad practice / a sign that the class does too many things. Consider (at least) giving it a more accurate name for your needs.
Demo: https://3v4l.org/iTmY6
Non-OOP alternative
function create_tables(Brands $brand_obj): void {
$brand_obj->create_brand_table();
}
function delete_tables(Brands $brand_obj): void {
$brand_obj->delete_brand_table();
}
$brand_obj = new Brands();
create_tables($brand_obj);
delete_tables($brand_obj);

PHP Classes function inside function?

I'm self-studying the PHP language. And I'm focused on the latest PHP OOP language.
I search for some "ready-to-install" PHP software and as I scan for some references to search and know, I saw lines of code with a structure like this (can't remember so I'll create my own):
$myapp->settings->getValue('openforum');
$myapp->settings->setValue('closeformaintenance', '1');
So my question is, how can I reproduce the code above? I don't know what term to use that line of code (objects, I guess?).
Something like this:
$newLogin->search($uid)->setLogin($dateToday);
Like that. I really need to do that way so I can organize my coding structure. Thanks by the way.
And also for the final question, IS THAT POSSIBLE?
Here's a fairly straight forward way of looking at it, using dependency injection.
Try it out: https://3v4l.org/iSJgL
Note, the below requires PHP 7 due to the string type hint. Remove that and I believe it should work in 5.6 just fine.
<?php
$myapp = new MyApp(new SettingsBag([
'works' => false,
'random' => rand(),
]));
var_dump($myapp->settings()->get('random'));
var_dump($myapp->settings()->get('works'));
// Let's change it up...
$myapp->settings()->set('works', true);
// Now it should be true.
var_dump($myapp->settings()->get('works'));
These would normally have namespaces like \App and/or \App\Configuration, but I ignore that here so it's easier to follow:
class MyApp {
private $settings_bag = null;
function __construct(SettingsBag $settings_bag)
{
$this->settings_bag = $settings_bag;
}
public function settings()
{
return $this->settings_bag;
}
}
class SettingsBag {
private $settings = null;
function __construct(array $settings = [])
{
$this->settings = $settings;
}
public function set(string $key, $value)
{
return $this->settings[$key] = $value;
}
public function get(string $key)
{
return $this->settings[$key];
}
}
What you try to achieve is called method chaining. You can get this by the following:
<?php
class TestClass {
private $val = '';
public function test1($val) {
$this->val = $val;
return $this;
}
public function test2() {
echo 'Hello '.$this->val;
}
}
$test->test1('World')->test2(); // Hello World
You have simply to return the instance of the object on the method to allow the method chaining.
You can read more here.
It's method chaining.
See code below:
class T {
public function test() {
// do something
return $this;
}
}
$x = new T;
$x->test()->test();

PHP - Closure in class , getting private property

I'm attempting to get a private property from another class using closures, as explained here:
http://ocramius.github.io/blog/accessing-private-php-class-members-without-reflection/
So, I'm trying to get the $wheelCount property.
But I keep getting
Fatal error: Cannot access private property Car::$wheelCount
So my car class is:
class Car
{
private $wheelCount = 4;
public function __construct($wheely)
{
echo $wheely->getWheels($this);
}
}
and then
class getThoseWheels
{
public function getWheels($that)
{
$wheels = Closure::bind($this->getPrivate($that), null, $that);
var_dump($wheels);
}
public function getPrivate($that)
{
return $that->wheelCount;
}
}
which is run:
$wheely = new getThoseWheels();
new Car($wheely);
$wheels = Closure::bind($this->getPrivate($that), null, $that);
The problem is that you're executing $this->getPrivate(), and this method is trying to access a private property. All this happens before Closure::bind is being involved at all. You're supposed to use it like this:
$wheels = Closure::bind(function () { return $this->wheels; }, $that, $that);
Or possibly:
$wheels = Closure::bind([$this, 'getPrivate'], null, $that);
I haven't tested this, but at least this has a much better chance of succeeding than your code.

PHP/Xdebug Nesting level error

Yes I looked at the previous questions in this topic and I still was not able to solve the problem. I tried ini_set('xdebug.max_nesting_level', 5000); in my script and still Im getting the error. So I will show you what I'm doing to hopefully get some and and get to a resolution.
Basically I running a test with data from my database.
include 'testSettings.php';
//get config
$conf = Config::getInstance('sendCsv.php');
$conf->getConfig();
$formatter = new FormatterContext(new CSVFormatter($conf));
$formatter->formatLoads(null);
The complain comes when I call `$formatter->formatLoads(null);
So here is FormatterContext()
class FormatterContext
{
private $strategy;
public function __construct(IFormatter $formater)
{
$this->strategy = $formater;
}
public function formatLoads()
{
return $this->formatLoads();
}
}
The interface:
abstract class IFormatter
{
private $config;
private $formatted;
private $fileMaps;
private $fileRows;
abstract public function formatLoads($loads);
public function __construct(Config $conf)
{
$this->fileMaps = $conf->__get('fileMaps');
$this->fileRows = $conf->__get('fileRows');
}
}
The Strategy:
class CSVFormatter extends IFormatter
{
public function formatLoads($loads)
{
echo "hello world!\n";
}
}
Now I really don't know what am I doing wrong here. This is the first time I have encounter this error. Beyond nesting level = 5000 I have not tried, I think at that point something is really wrong. Thanks
Arg! Silly me... In the context class I'm calling the context formatLoad() instead of the strategy. Ooops!
The context class should be like:
class FormatterContext
{
private $strategy;
public function __construct(IFormatter $formater)
{
$this->strategy = $formater;
}
public function formatLoads()
{
// return $this->formatLoads();
return $this->strategy->formatLoads();
}
}

PHP - passing variable from one object to another troubles

I've recently started to work with OO PHP. As a training practice I'm trying to write some simple classes. I have trouble passing a variable from one to another class. Is it even possible?
class group
{
public $array = array();
public function person($name,$surname)
{
$this->person = new person($name,$surname);
}
public function __destruct()
{
print_r($this->array);
}
}
class person
{
public function __construct($name,$surname)
{
$this->name = $name;
$this->surname = $surname;
}
}
$A = new group();
$A->person("John","Doe");
What I want to archieve here is to pass person as another member of group (by simply putting it in group array) for further modifications and sorting. Been googling around but found nothing.
Please forgive me if it's a dumb one. ;)
I'm not sure I totally understand but I think you want:
Class group {
public $members=array();
public function person($name,$surname) {
$this->members[]=new person($name,$surname);
//Creates a new person object and adds it to the internal array.
}
/*...*/
}
A better alternative (seperation of intent) would be:
Class group {
public $members=array();
public function addPerson(person $p) {
$this->members[]=$p;
//Avoids this function need to know how to construct a person object
// which means you can change the constructor, or add other properties
// to the person object before passing it to this group.
}
/*...*/
}
The fix is changing
public function person($name,$surname)
{
$this->person = new person($name,$surname);
}
to
public function person($name,$surname)
{
$this->array[] = new person($name,$surname);
}
$this->person is not being stored in the array otherwise, and is overwritten with each call.
Your group class could improve it's OO by:
changing $array to be more descriptively named
changing the function name person to something more meaningful, like add_person
You should define your properties ('name', 'surname') and give them a suitability visibility
class group
{
public $array = array();
public name;
public surname;
...
Reference: http://php.net/manual/en/language.oop5.visibility.php

Categories