ZF2 - Call to a member function on a non-object error - php

I am trying to implement a simple roll-a-dice service and use it in a .phtml file. I know my issue has been reported often on SO, but I could not find a solution in other questions.
I get the following error message:
Fatal error: Call to a member function getDiceResult()
on a non-object in rolladice.phtml on line 11
Here is line 11:
<?php
$result = $this->rollADiceService->getDiceResult();
echo "<p>Roll-a-dice result: ".$result."</p>";
?>
The controller is set-up as following:
class RollADiceController extends AbstractActionController
{
private $rollADiceService;
public function setPluginManager(PluginManager $plugins) {
parent::setPluginManager($plugins);
$this->rollADiceService = $this->getServiceLocator()
->get('RollADiceService');
}
...
In Module.php, I have:
public function getServiceConfig()
{
return array(
'factories'=>array(
'LoginLogoutService' => function() {
return new LoginLogoutService();
},
'RollADiceService' => function() {
return new RollADiceService();
},
),
);
}
I am using the same technique (i.e., setPluginManager) to retrieve instances of my services in other controllers without issues. What am I doing wrong?
P.S.: Using a debugger, I can see that setPluginManager() is called, but that the $this->rollADiceService variable is initialized with null. Why?

Ultimately, there were two issues:
i) I refactored my code to pass the result of the call to rollADiceService->getDiceResult() as a variable which $this can access.
ii) Hijacking setPluginManager() is not a recommended practice. I've implemented factories for my controllers depending on services.

your problem is realy simple I think.
<?php
$result = $this->rollADiceService()->getDiceResult();
echo "<p>Roll-a-dice result: ".$result."</p>";
?>
Add these brackets after rollADiceService should fix your problem. Without brackets, Zend View instance try to access to view variable named rollADiceService, which is obviously NULL.
By adding brackets, you tell to View it should look for rollADiceService in registered view helpers.
I hope it helps :)

Related

Laravel app::call('SomeController#method') not working

I want to be able to call a method inside a controller in the following manner:
App::call('SomeController#method');
I figured it happens like this when defining a route:
Route::get('/route', 'SomeController#method');
So maybe there's an underlying mechanism I can use more generally in my code on other places in the project, turns out there is (App::call()).
The problem I'm running into is that this generates an error:
ReflectionException (-1)
Class SomeController does not exist
## \vendor\laravel\framework\src\Illuminate\Container\Container.php
public function build($concrete)
{
// If the concrete type is actually a Closure, we will just execute it and
// hand back the results of the functions, which allows functions to be
// used as resolvers for more fine-tuned resolution of these objects.
if ($concrete instanceof Closure) {
return $concrete($this, $this->getLastParameterOverride());
}
$reflector = new ReflectionClass($concrete);
// If the type is not instantiable, the developer is attempting to resolve
// an abstract type such as an Interface of Abstract Class and there is
// no binding registered for the abstractions so we need to bail out.
if (! $reflector->isInstantiable()) {
return $this->notInstantiable($concrete);
}
$this->buildStack[] = $concrete;
$constructor = $reflector->getConstructor();
I'm pretty sure I must include some stuff somewhere but since Laravel is pretty big I'm asking this community.
Try giving the full namespace like:
App::call('App\Http\Controllers\SomeController#method');
Another way is:
app()->call(['\App\Http\Controllers\SomeController', 'index']);
where index is the name of the method. You can add a second parameter to send some data like so:
app()->call(['\App\Http\Controllers\SomeController', 'index'], [
'name' => 'Strawberry'
]);
You can call the method by using the app() helper. Syntax is app($fullControllerClassName)->methodYouWantToCall():
app('App\Http\Controllers\SomeController')->method();

How to Access $this variable inside nested functions in codeigniter?

I have a controller for Nu soap WSDL Like:
class webservice extends CI_Controller
{
function index()
{
$this->load->library('encrypt');
$this->load->model('MWSDl');
//...
function buy($apicode)
{
if(!$this->MWSDl->check_gateway($apicode)) //Error occurred php Cannot find "$this" Variable
}
//...
$this->nusoap_server->service(file_get_contents("php://input"));
}
}
How to Access $this inside buy function?
I tried by global $this But Error occurred!
Error:
Fatal error: Using $this when not in object context in \controllers\webservice.php on line 9
You are going wrong about the whole concept. PHP is not Javascript.You shouldn't nest functions, specially not when using OOP frameworks. If you run function index twice, the second time you will probably get an error that function buy is already declared since first run of index will declare function buy.
I would declare them as class member functions / methods.
class Webservice extends CI_Controller {
function __construct()
{
parent::construct();
$this->load->library('encrypt');
$this->load->model('MWSDl');
}
function index()
{
// do something like
$apicode = 'xxxxxx';
$this->buy($apicode);
//or what ever else you need to do
}
function buy($apicode)
{
if(!$this->MWSDl->check_gateway($apicode)) {
$this->nusoap_server->service(file_get_contents("php://input"));
}
}
}
No need to use globals in codeigniter.
Let me know if this helps.
I understand your question. I also had the same problem with nusoap. When registering a service you have to make a function. Thus in CI you are creating it inside a class function which makes the service function is nested inside, and cannot be taken outside.
Why don't you try this below? I use it all the time before, with helper etc. It's simple and I have tried it and it works.
Put this inside your nested function:
$ci =& get_instance();
and the rest you have to replace $this with $ci
eq. $ci->some_model->some_function(); or $ci->some_var = 'something';
And it also work if you tried to call a db.
I hope this will help you.

php OOP - call static method from another class within class

I have the following class to another class in my main class.
class Products
{
public function __get( $key ){
return trim(functions::mssql_escape_string_rev($this->fields[ $key ]));
}
}
This beings back error: Call to undefined method functions::mssql_escape_string_rev()
Is there something wrong with my syntax or can this not be done?
Below is code used to autoload classes, this works for everything else so I know there is nothign wrong with the code. It just doesnt seem to initiate within the class.
// autoloader function called when we try to instantiate a class but haven't included the file
function __autoload($resource_name){
$resource_name = trim($resource_name);
try {
$filepath = CLASS_PATH."/class.".$resource_name.".inc.php";
if(#!include($filepath)){
throw new Exception('');
}
} catch(Exception $e) {
exit("Could not find the required file: ".$resource_name);
}
}
*******EDIT*****
Please ignore this, I made a stupid mistake and included the functions::mssql_escape_string_rev twice. Sorry for timewasting..
As the error says the problem is that functions::mssql_escape_string_rev() is not defined.
Since we can't see what you think is the definition we can not really help you.
For me it looks like the call should be Functions::mysql_escape_string_rev() with capital F and mysql.
Update
Calling static functions from another class works normally: http://codepad.org/wrfm5X7j
Maybe you are calling mysql_escape_string_rev before you included the functions class.

PHP5 Class scope quirks

Hey php gurus. I'm running into some bizarre class scope problems that clearly have to do with some quirk in php. Can anyone tell me what out-of-the-ordinary situations might give the following error...
Fatal error: Cannot access self:: when no class scope is active in MyClass.php on line 5
Now, obviously if I were to use self:: outside of the class, I'd get errors... but I'm not. Here is a simplified version of the situation...
//file1
class MyClass{
public static function search($args=array()){
$results = MyDbObject::getQueryResults("some query");
$ordered_results = self::stack($results); //Error occurs here
return $ordered_results;
}
public static function stack($args){
//Sort the results
return $ordered_results;
}
}
//file 2
include_once("MyClass.php");
$args = array('search_term'=>"Jimmy Hoffa");
$results = MyClass::search($args);
given this setup how can I get the error above? Here is what I've found so far...
MyClass::search($args) //does not give the error (usually)
call_user_func("MyClass::search"); // this gives the error!
Any other situations?
If I understand correctly, you are looking for Late Static Binding. This feature requires PHP version 5.3 at least.
You're not passing any parameters, but your method is looking for them. Try
call_user_func("MyClass::search", $args);
This works in php 5.3.1, but call_user_func("MyClass::search"); doesn't
Try this:
call_user_func(array('MyClass', 'search'));
See also example #4 on http://php.net/call_user_func
Your code seems fine. If there's something wrong with it, I must be missing the problem. It appears that your call to self:: is totally within the scope of a class! And a static scope, specifically, which is what self:: is for.
From the 3rd Edition of PHP Objects Patterns and Practice (an awesome book):
To access a static method or property from within the same class
(rather than from a child), I would use the self keyword. self is to
classes what the $this pseudo-variable is to objects. So from outside
the StaticExample class, I access the $aNum property using its class
name:
StaticExample::$aNum;
From within the StaticExample class I can use the self keyword:
class StaticExample {`
static public $aNum = 0;
static public function sayHello() {
self::$aNum++;
print "hello (".self::$aNum.")\n";
}
}
So, I am not sure why this code was failing. Perhaps a PHP bug? I came upon this error when actually trying to use self:: outside of the scope of a class-- my error looked like this:
public static function get_names() {
$machine_names = self::get_machine_names();
return array_map(function ($machine_name) {
$service_settings = self::get_settings_by_machine_name($machine_name);
return $service_settings . $machine_name;
},
$machine_names
);
}
So, I get the error because I use self:: within the scope of the closure. To fix the error, I could make that call to self::get_settings_by_machine_name() before the closure, and pass the results to the closure's scope with use.
Not sure what was happening in your code.

PHP Callable Object as Object Member

I have a class Logger which, among other things has a method Log.
As Log is the most common use of the Logger instance, I have wired __invoke to call Log
Another class, "Site" contains a member "Log", an instance of Logger.
Why would this work:
$Log = $this->Log;
$Log("Message");
But not this:
$this->Log("Message");
The former fails with "PHP Fatal error: Call to undefined method Site::Log()"
Is this a limitation of the callable object implementation, or am I misunderstanding something?
Unfortunately, this is (still) a limitation of PHP, but it makes sense when you think about it, as a class can contain properties and methods that share names. For example:
<?php
class Test {
public $log;
public function __construct() {
$this->log = function() {
echo 'In Test::log property';
};
}
public function log() {
echo 'In Test::log() method';
}
}
$test = new Test;
$test->log(); // In Test::log() method
call_user_func($test->log); // In Test::log property
?>
If PHP were to allow the syntax you desire, which function would be invoked? Unfortunately, that only leaves us with call_user_func[_array]() (or copying $this->log to another variable and invoking that).
However, it would be nice if the following syntax was acceptable:
<?php
{$test->log}();
?>
But alas, it is not.
Same reasons you can't do this:
$value = $this->getArray()["key"];
or even this
$value = getArray()["key"];
Because PHP syntax doesn't do short hand very well.
This may work:
${this->Log}("Message");
But perhaps it's just easier and better to use the full call? There doesn't seem to be a way to get what you want to work on the one line.
The error in your question indicates it is looking for a function defined on the class which doesn't exist. An invokable object isn't a function, and it seems it can't be treated as one in this case.
as of php7.4 the following code works for me
($this->Log)("Message");

Categories