Getter method cannot access its own property - php

I have the following entity Model with property float $price.
When I create such a getter method:
public function _getPrice()
{
return $this->price*100;
}
It keeps giving me the following error:
Undefined property: App\Model\Entity\Model::$price
What's the problem?

You are essentially trying to access a getter method from within itself.
In order for this to work, try rewriting it as follows:
public function _getPrice()
{
return $this->_properties['price'] * 100;
}

Related

Non-static method App\Console\Setting::KS() should not be called statically - Laravel

I have made my own class
<?php
namespace App\Çonsole;
use App\KernelSetting;
class Setting
{
/**
* #param $setting
* #return
*/
function KS($setting)
{
return KernelSetting::where('setting', $setting)->first()->value;
}
}
Now I am calling it like this Setting::KS('review_time_limit')
How do I return the value from the database entry I get?
I get this
Non-static method App\Console\Setting::KS() should not be called statically
The error message is pretty clear, you need to make the method static in order to call it like that.
static function KS($setting)
{
return KernelSetting::where('setting', $setting)->first()->value;
}
You can read more about static here :
https://www.php.net/manual/en/language.oop5.static.php

ErrorException: Indirect modification of overloaded property App\Answer::$attribute has no effect

I get this exception when Answer model I am trying to change value of 'ans' attribute from my answers table database.
public function setAnsAttribute($ans){
}
ErrorException: Indirect modification of overloaded property
App\Answer::$attribute has no effect
The setAnsAtribute method has no code? If you have code, please add more code to see what is happening. Thank you.
If you do not have a code, I will indicate it below.
I refer you to the Laravel Mutators page so you can see the example and attach an example code with what you are trying to do.
función pública setAnsAttribute ($value) {
/**
* You can transform the value or modify other values in the table here,
* according to your needs.
*/
$this->attributes['ans'] = $value;
}
I have never encountered this error so I did a little research and created the following to illustrate the issue:
The class:
class SomeMagicMethodImplementer
{
private $properties = [];
public function __get($k)
{
return $this->properties[$k] ?? null;
}
public function __set($k, $v)
{
$this->properties[$k] = $v;
}
}
The usage:
$impl = new SomeMagicMethodImplementer();
$impl->bar = 'bar';
print_r($impl->bar); // prints bar
$impl->foo[] = 'foo';
The cause of the error:
$impl->foo[] = 'foo' // Will throw error: Indirect modification of overloaded property
Indirect modification of overloaded property
Using the example code above, this error essentially states that any property created via the magic setter can only be modified through the private instance variable $properties.
In the context of Laravel and a model, the property can only be modified through the protected instance variable $attributes.
Laravel Example:
public function setAnsAttribute($value)
{
// output will be an array
$this->attributes['ans'][] = $value;
}

Why my getter (__get) is not called in PHP class?

I have read all related question, but failed to remove the bug from my code. Please guide me about possible error in my code.
When I try to call following code, it reports Error: Call to undefined method SessionManager::close() in E:\wamp64\www\mjs-cms\private\systemcore\helper\SessionManager.php on line 22 instead of "tried to call close".
Thanks in advance.
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class SessionManager{
public function __construct() {
session_start();
}
public function is_exist($a){
return isset($_SESSION["system".$a]);
}
public function add($a,$b){
$_SESSION["system".$a]=$b;
}
public function addCookies($a,$b){
setcookie($a, $b, time() + (86400 * 30), "/"); // 86400 = 1 day
}
public function sessionKey(){
return session_id();
}
public function value($k){
if(!isset($_SESSION[$k]))
$this->close("SESSION_NOT_DEFINED".__LINE__);
return $_SESSION[$k];
}
public function __get($key)
{
echo "tried to call $key";
return get_instance()->$key;
}
}
__get method is for accessing undeclared properties of a class.
For calling undeclared functions is __call or __callStatic.
public function __call($method_name, $arguments)
{
echo "tried to call: $method_name";
}
If you want to use __get - you must call for undefined property. In this case it is not
SessionManager::close() // call method `close()`
It must be:
$sm = new SessionManager;
$sm->propertyName; // trying to access undefined property `propertyName` of an object
Take into consideration that
Property overloading only works in object context.
which means that trying to access static property like
SessionManager::staticProperty;
will not work with __get.

unserialize() ... Function spl_autoload_call() hasn't defined the class it was called for

I'm using factory to create an object and the static method to unserialize this object:
public static function factory($idText) {
$fetchedObject = self::fetchStoredObject($idText);
return $fetchedObject;
}
private static function fetchStoredObject($idText) {
$fetchedText = DB::select()
->from(table)
->where('idText', '=', $idText)
->execute()->as_array();
if (!empty($fetchedText)) {
return unserialize(base64_decode($fetchedText[0]['txtContent']));
} else {
return NULL;
}
}
The object is created in this way:
$text = Article::factory($idText);
But I get the following error:
unserialize() [<a href='function.unserialize'>function.unserialize</a>]:
Function spl_autoload_call() hasn't defined the class it was called for
On this line of fetchStoredObject method:
return unserialize(base64_decode($fetchedText[0]['txtContent']));
Why does this error occur?
EDIT
My class has the following structure:
class Article {
private $phpMorphy;
private $words; //contains instances of class Word
...
private function __construct($idText) {
$this->initPhpMorphy(); // $this->phpMorphy gets reference to the object here
}
public function __sleep() {
return Array(
'rawText',
'idText',
'properties',
'words',
'links'
);
}
public function __wakeup() {
$this->initPhpMorphy();
}
}
The Word class doesn't contain the reference to phpMorphy as own property, but uses it in its methods as function parameter.
Here is the part of the serialized string:
" Article words";a:107:{i:0;O:4:"Word":10:{s:5:" * id";O:9:"phpMorphy":7:{s:18:" * storage_factory";O:25:
It appears the phpMorphy is serialized with connectrion to the Word class. Am I right?
The error occurs because inside your serialized string there is a reference to a class that hasn't been included yet - so the PHP autoloading mechanism is triggered to load that class, and this fails for some reason.
Your steps for debugging would be:
Identify which class is included in that serialized string.
Check if you have code for that class somewhere.
Make sure this code can be loaded via autoloading. Alternatively make sure that code is included before unserializing.
What version of PHP did you use? Where did you store your Article class? Try to require() it manually.
The problem is fixed thanks to Sven suggestions. The object of class Word (part of the class Article) contained reference to the phpMorphy class (which happened because I changed parameters order when creating an instance of the word!).

Pass the current class as parameter

I have a class like this:
// file /models/person.php
class Person
{
public function create_path()
{
self::log();
path_helper($this); //a global function in other php file
}
public function log()
{
echo "trying to create a path";
}
}
This is the way how Person is instanciated:
//file /tools/Builder.php
include('/models/Person.php');
class Builder
{
public function build()
{
$type = 'Person';
$temp = new $type();
$temp->create_path();
}
}
As you note in Person class, I am calling the object in question with $this reference. But this is not correct because an error is showed:
Message: Undefined variable: this
I suppose that $this reference point to other object or it is unable to work because the object is created from another script. Also, I tried to use self because there was not problem calling methods with that, but as parameter I get:
Message: Use of undefined constant self - assumed 'self'
So, can you guide me to the right direction?
I tested your code out for myself, with a few minor changes. It appears to work properly.
Changed self::log() to $this->log()
Added global function path_helper (I have no idea what this does)
PHP
function path_helper(Person $object)
{
var_dump($object);
}
class Person
{
public function create_path()
{
$this->log();
path_helper($this); //a global function in other php file
}
public function log()
{
echo "trying to create a path";
}
}
class Builder
{
public function build()
{
$type = 'Person';
$temp = new $type();
$temp->create_path();
}
}
$Build = new Builder();
$Build->build();
Result
trying to create a path
object(Person)[2]
Your code is correct and your going in the right direction.
You should call the log method like this:
$this->log();
because using self:: is reserved for static methods.
Also, try calling the path_helper function like this:
path_helper(self);
Hope I could help you. Couldn't test it, but it should work.

Categories