Access to undeclared static property php fatal error - php

I am getting this error: Access to undeclared static property: DBug::$errorMsg
Following is the code
class DBug
{
private static $errorMsg = array(
1 => 'inv-req',
2 => 'inv-reqPrm',
3 => 'no-set',
4 => 'less-h',
5 => 'less-w'
);
public static function showTinyErrMsg($errCode=0)
{
if(SHOW_ERROR_MSG_IN_RESPONSE === TRUE) {
if(array_key_exists($errCode, self::$errorMsg)) {
echo "// ".self::$errMsg[$errCode].";\n" ;
}
}
}
}
I call this function by DBug::showTinyErrMsg(1);. I get the above mentioned error. I am surely missing some OO rule, please help me with this.
P.s: The reason for this class having all static member is, that it's a long standing class with all static members, so I had to add this new method as static

The property is $errorMsg, but you're calling $errMsg.

Related

Dynamic methods with parameters typing in PHP

I have the PHP legacy code below that intends to return the name of a method dynamically.
public function getMethod($fieldName){
//do stuff
return $methodName;
}
The returned method names are something like:
setClient
setName
setAge
All right here.
The problem is when I use these methods. I have a class named Model, that has the folowing method:
class Model {
public function find () {
$nameClass = get_called_class();
$instance = new $nameClass;
$result = $this->conn->select();//the select method returns a SQL SELECT from the database
if (isset($result[0])) {
foreach ($result[0] as $key => $val) {
$methodProp = $this->getMethod(key);
$instance->$methodProp($val);
}
} else {
throw new Exception('You have a error in your class');
}
}
}
Here is the var_dump($result) as requested:
array (size=1)
0 =>
object(stdClass)[6]
public 'id' => string '1' (length=1)
public 'id_erp' => string '0' (length=1)
public 'name' => string 'Derp' (length=18)
public 'email' => null
public 'type_ota' => null
public 'user' => string 'derp_derp' (length=7)
public 'password' => string '1234' (length=4)
public 'url_logo' => null
public 'status' => string '1' (length=1)
public 'date' => string '2015-06-08 14:41:50' (length=19)
Then I have some classes that extends this Model:
class Company extends Model {
public function setClient (Client $cli) {
//do stuff
}
public function setName($name) {
//do stuff
}
public function setAge($age) {
//do stuff
}
}
//here I use the class
$myCompany = new Company();
$myCompany->find();
The methods setName() and setAge() works fine, but setClient() returns
Catchable fatal error: Argument 1 passed to setClient() must be an instance of Client, string given
In short, how can I deal with dynamic methods and typing in PHP?
Looking for help, I found something about Reflection, but I never used this class before and the examples that I found didn't help me, although I think that it's the right way.
Has anyone had a similar experience?
UPDATE
I tried to put some code in my question to clarify my problem.
If I understand your question correctly, you want to check what typehint the method wants. I took this code snippet from the docs.
<?php
//Target our class
$reflector = new ReflectionClass('MyClass');
//Get the parameters of a method
$parameters = $reflector->getMethod('FireCannon')->getParameters();
//Loop through each parameter and get the type
foreach($parameters as $param)
{
//Before you call getClass() that class must be defined!
echo $param->getClass()->name;
}
To add the code above to your code. This would check if the parameter in the method is an object, if is an object it will check that the class is the same as the value given. If the parameter is not an object, you can either just call the method, or if you typehint your non-object parameters, you can check that they are equal as well. This code should definitely be modified and cleaned up, but I thought it would be enough to get my point across.
class Model {
public function find () {
$nameClass = get_called_class();
$instance = new $nameClass;
$result = $this->conn->select();//the select method returns a SQL SELECT from the database
if (!isset($result[0])) {
throw new Exception('You have a error in your class');
}
foreach ($result[0] as $key => $val) {
$methodProp = $this->getMethod($key);
$reflector = new ReflectionClass($nameClass);
$reflectorMethod = $reflector->getMethod($methodProp);
// Make sure method doesn't require more than one param,
// and it has defined at least one param.
if ($reflectorMethod->getNumberOfRequiredParameters() > 1 ||
$reflectorMethod->getNumberOfParameters() < 1
) {
// Throw error
}
//Get the parameters of a method
$parameters = $reflectorMethod->getParameters();
if (is_object($parameters[0])) {
if (!is_object($val) {
// Throw error
}
//Before you call get_class() that class must be defined!
//Use either class_exists($nameClass); or
//in_array($nameClass, get_declared_classes()); to check.
if ($val->getClass()->name !== get_class($parameters[0])) {
// Throw error
}
} else if (gettype($parameters[0]) !== gettype($val)) {
// Throw error
}
$instance->$methodProp($val);
}
}
}
Your problem is here
public function setClient (Client $cli) {
//do stuff
}
See how you have a class name next to the argument? That's called type hinting. It means that argument MUST be an instance of the class you specified or you'll get the error you posted. Somewhere in your code you're calling
$method($param);
And $param is not an instance of Client. So that is what you have to fix. Whatever calls setClient has to have an instance of Client.
$param = new Client();
$method($param);

Class method don't exists (throwing fatal error) - But it exist

I don't know why, but PHP triggers a Fatal Error because a Class Method doesn't exist.
But it clearly exists!
left.phtml:
<?php
$block = Block::getBlock('core/sidebar_modules');
foreach($block->getSidebar('left') AS $key => $value)
{
$_block = explode('_',$value->getName());
if(isset($_block[1]))
{
$_block[1] .= '_widget';
}
$loadBlock = Block::getBlock(implode('/',$_block)); // returns instance of Visio_Blog_Block_Recent_Widget
Debug::var_dump($loadBlock);
/*
returns:
object(Visio_Blog_Block_Recent_Widget)#33 (0) {
}
*/
echo $loadBlock->widgetContent();
/*
returns:
Fatal error: Call to a member function widgetContent() on a non-object in E:\docroot\vhosts\zend.local.host\htdocs\app\design\default\templates\left.phtml on line 13
*/
Debug::print_r(get_class_methods($loadBlock));
/*
returns:
Array
(
[0] => __construct
[1] => widgetContent
)
*/
}
?>
Widget.php (Visio_Blog_Block_Recent_Widget)
Class Visio_Blog_Block_Recent_Widget
{
public function __construct()
{
return $this;
}
public function widgetContent()
{
return 'content';
}
}
I have no clue why this happens?
Is it possible that this is an Error off my View Class while implementing nested view Templates.
I built the framework from scratch.
from the error it looks like that $loadBlock does not contain an instance of Visio_Blog_Block_Recent_Widget or any class, for that matter.
So the problem is around assigning.

Undefined property and Undefined index when referencing a class from within another class

I am currently working on a large project for a client, and to help simplify things and make managing sessions easier I have made a session class, this means that if I ever change the way I manage my sessions I can access the structure of the sessions in one file rather then multiple files where a session has been echoed (Such as the users name or the current page)
My class has 3 types of functions setters, getters and unsetters which is kind of self explanatory.
Now in this instance I am setting an error message to the session class directly and then getting the error messages from another class which calls a function from the session within it.
Below are simplified versions on my files showing code I feel is relevent
c_session.php
class session {
private $instance = 'isntname';
private $A_user = 'user';
private $A_page = 'page';
private $A_message = 'message';
//Set messages to the session.
public function set_message($type, $value) {
$_SESSION[$this->instance][$this->A_message][$type] = $value;
}
//Get messages from the session.
public function get_message() {
return $_SESSION[$this->instance][$this->A_message];
}
//Unset messages from the session.
public function unset_message() {
#unset($_SESSION[$this->instance][$this->A_message]);
}
}
c_operations.php
class operations {
//Display all pending messages.
public function display_pending_messages() {
if(session::get_message() != null) {
foreach(session::get_message() as $type => $value) {
if(strlen($type) != null) {
echo '
<div class="panel ' . $type . '">
' . $value . '
<span class="close" onclick="hide_parent_element(this);">X</span>
</div>
';
}
}
session::unset_message();
}
}
}
example.php
$session->set_message('confirm', 'THIS IS A CONFIRM');
$session->set_message('error', 'THIS IS AN ERROR');
$session->set_message('notice', 'THIS IS A NOTICE');
$session->set_message('warning', 'THIS IS A WARNING');
var_dump($_SESSION);
$operation->display_pending_messages();
Errors/notices etc received
Notice: Undefined property: operations::$instance in /var/www/_classes/parent_session.php on line 43
Notice: Undefined property: operations::$A_message in /var/www/_classes/parent_session.php on line 43
Notice: Undefined index: in /var/www/_classes/parent_session.php on line 43
Line 43 refers to the line return $_SESSION[$this->instance][$this->A_message];
Now if I call get_message() and unset_message() directly via $session->get_message() it works as expected but going through another function in this case $operation->display_pending_messages() it returns the above errors. Obviously this has something to do with the $this-> operator but I'm not to sure on what to do to stop this. I have tried various searches and while finding something similar it wasn't helpful in this case.
Can someone please explain where I've gone wrong and how to fix this?
Thanks in advance.
In class operations you call your session as static but all your data is in an object.
The best way is to store in a static, all data of your class session :
`
class session {
private static $instance = 'isntname';
private static $A_user = 'user';
private static $A_page = 'page';
private static $A_message = 'message';
//Set messages to the session.
public static function set_message($type, $value) {
$_SESSION[self::instance][self::A_message][$type] = $value;
}
//Get messages from the session.
public static function get_message() {
return $_SESSION[self::instance][self::A_message];
}
}
And so you can call all your functions with session:: in your code, without create object session
You are trying to call these functions statically, but they are instance methods. e.g session::get_message() Try either adding the static keyword to the functions or better still pass in instantiated class and call the methods with $session->get_message()
public function display_pending_messages($session) {
if($session->get_message() != null) {
etc.

PHP Fatal Error: Cannot use object of type DataAccess as array

I cannot figure out why I am getting the following error in PHP:
Fatal error: Cannot use object of type DataAccess as array in /filename on line 16.
Here is the relevant code for the file:
class StandardContext implements IStandardContext
{
private $dataAccess;
// (CON|DE)STRUCTORS
function __construct($config)
{
$this->dataAccess = new DataAccess($config['db']); //this is line 16
}
$config refers to the following:
$config = require(dirname(__FILE__)./*truncated*/.'Config.php');
Here is the relevant code for Config.php:
return array(
// Database connection parameters
'db' => array(
'host' => 'localhost',
'name' => 'visum',
'user' => 'root',
'password' => ''
)
);
Here is the relevant code for the DataAccess object:
class DataAccess
{
private $link;
private $db;
function __construct($dbConfig)
{
$this->link = mysql_connect( $dbConfig['host'], $dbConfig['user'], $dbConfig['password'] ) or die(mysql_error());
$this->db = $dbConfig['name'];
mysql_select_db($this->db) or die(mysql_error());
}
Any help would be greatly appreciate, I am fairly new to PHP and am absolutely stumped.
Edit: BTW, I have included the following code to test StandardContext, which actually works (ie. it allows me to make changes to my database farther down than I have shown)
class StandardContext_index_returns_defined_list implements ITest
{
private $dataAccess;
function __construct($config)
{
$this->dataAccess = new DataAccess($config['db']);
}
It's almost like you are trying to use a singleton pattern, but for every StandardContext object you instantiate, you are passing in database parameters (via $config array). I think what's happening is that you are passing the $config array more than once, after the first pass the $config is no longer an array, but an instance of the DataAccess class, which is why you are getting that error. You can try the following:
class StandardContext implements IStandardContext
{
private $dataAccess;
// (CON|DE)STRUCTORS
function __construct($config)
{
if ($config instanceof DataAccess) {
$this->dataAccess = $config;
} elseif ((is_array($config)) && (array_key_exists('db', $config))) {
$this->dataAccess = new DataAccess($config['db']);
} else {
throw new Exception('Unable to initialize $this->dataAccess');
}
}
this is problem with your
private $dataAccess;
check the array object here
http://www.php.net/manual/en/class.arrayobject.php
whenever you declare outside a method inside class, it will consider as Object , so you have to declare inside method or declare as method itself else remove implements from your class.
your $dataAccess is an Object , because you declare it outside the method and your new DataAccess($config['db']) will return an arrayObject because you implements that, so it is trying to convert from Object to arrayObject leads an error

PHP : $this->methodcall() gives error and CalledClass:methodcall() works fine

I am trying to call method getDetails() from another class which in turns calls to methods from its own class(i.e, called class) and it does so by
$this->getAccount() and $this->getAddress() and in called class we have methods like $this->getAccount() and $this->getAddress() function but when I call
them I get fatal error message as call to undefined method, but when I try calling that method using CalledClassName::getAddress() and
CalledClassName::getAddress() than it works fine.
My question is that class which am calling(i.e, calledClass ) will always have use $this->getAddress() and $this->getAccount() as am getting this class
information from other team and there are 3 teams that would be calling functions getDetails() which would internally call getAccount() and getAddress()
functions and so how should I deal with the issue of $this on myside when am calling getDetails() function.
Code Example
Calling Class:
CalledClass::getDetails() // Call to getDetails function in CalledClass
CalledClass::
public function postalAddress()
{
return array(
'addressId' => $address->addressId,
'city' => $address->city,
'country' => $address->country,
'postcode' => $address->postcode,
'stateOrProvince' => $address->stateOrProvince,
'street' => $address->streetName,
'streetNumber' => $address->streetNrFirst,
'streetSuffix' => $address->streetNrFirstSuffix
);
};
public function getAddress()
{
return $this->postalAddress();
}
public function setAccount($account)
{
$this->account = $account;
}
public function getAccount()
{
return $this->find('account = 1311143','');
}
public function getDetails()
{
$data = array();
$data[$address] = $this->getAddress();
$data[$account] = $this->getAccount();
return $data;
}
So now using the above method it gives me error and so if am using CalledClass::getAddress() and CalledClass::getAccount() and it works fine but I cant chang e the code in the calledclass as am calling this function from another team.
Any guidance or suggestions ?
If the function you are trying to call from another class is static, you need to use the :: (scope resolution operator) to call on it. It is also the same way when trying to access static properties.
Because static methods are callable without an instance of the object created, the pseudo-variable $this is not available inside the method declared as static.
Taken from PHP: Static Keyword
In the meantime for your method call to work without having the ability to modify the other member's code is to use CalledClass::getAddress()

Categories