I was going through some tutorial and documentation about zend framework, most of things made sense until i came across $this variable in /application/layout/scripts/layout.phtml, it was mentioned that $this is an instance of the view object that was created during bootstrapping.
to my knowledge you cannot use $this as the variable name as because $this is a reserved keyword for php used to refer the same object within the class context. any attempt to use it as a variable will result in Fatal error with the following error message Fatal error: Cannot re-assign $this and as per the author's statement There is a variable, $this, available which is an instance of the view object, i am unable to understand the theory behind this. how come $this is being used out of the class context?
It's actually being used in the context of an object. You should look at the code yourself, but the basic idea behind render() (which is the toString method by proxy):
public function render()
{
//Start output buffering
ob_start();
include $this->viewScript;
//Get the content from the include
$content = ob_get_flush();
return $content;
}
Zend Framework does it a bit more complexly so that it's a bit more flexible than that, but it's the basic idea.
Then, inside of the viewScript, it's technically inside of the render() method just as if the code were literally in that "include ..." place. (Oversimplifying that, but the general idea holds.)
It's probably being used in the class context. Imagine the view being created along the following lines:
class View {
public function render($viewfile = 'views/myviewfile.phtml') {
ob_start();
include($viewfile);
$view_data = ob_get_contents();
ob_end_clean();
echo $view_data;
}
}
The view presentation process is probably more complex than simply capturing an included view file, but you can see how $this would be available to the view when View::render() is called.
Related
Just wondering if there is any way to dump and view the function/method definition inside the class using the Object name?
I found the way to get the class name and method name as well using an instantiated object name with this function:
public function getObjectMethods(object $obj) {
$className = get_class($obj);
//return $className;
return get_class_methods($className);
}
Also, I could access the properties in the class by using the var_dump; however, is there any way I could see the method/function definition inside the class?
Well AFAIK, there is no such function to see what code written on the function directly. (well, you can get the function line number and read the file with file_get_contents)
You could use Kint as a temporary option. It's uses reflection to deep dive into the class/object/instance.
https://github.com/kint-php/kint
Kint::dump($obj);
Reference: Am using Slim Framework to develop Rest API application.
Problem: While doing so, used static functions. However, one of the functions that were called from my api code, threw an error "Using $this when not in object context". Since I cannot change the code being called which is generating the issue, I need to change my code.
Sample Code before change:
$app->post($mer_token_endpoint, get_token);
The rest of the code is fine, except the issue of $this. Wherever it is not called, those APIs work fine.
Now I changed the code to:
class Token {
public function get_token(Request $request, Response $response, array $args) {
.... code ....
}
}
$TokenObj = new Token();
$app->post($token_endpoint, $TokenObj->get_token);
How do I pass the reference of the function get_token declared in the class Token in the function post ?
Your code seems right but i want to know more about your code. Do you use static property in your function because if you have static class or function we use self instead of $this to access static property also without creating object
I register class methods for actions in my Wordpress plugin. When my method gets called by Wordpress, if I try to use the $this variable, php throws an error saying the call to $this variable is illegal outside the context of an object.
How can that be? I thought unless the method is static, you're not supposed to be able to call class methods if the class isn't instantiated! My method isn't static! What is happening?
The source code
Obviously the initialize is called from the main plugin file:
add_action('init', array('AffiliateMarketting', 'initialize'), 1);
My class looks like this:
class AffiliateMarketting
{
public function __construct()
{
// some initialization code
}
public function initialize()
{
add_action('woocommerce_before_single_product', array("AffiliateMarketting", "handleAffiliateReferral"));
}
public function handleAffiliateReferral($post)
{
$this->xxx(); // <---- offending function call
}
public function xxx()
{
}
}
The received error message is in fact Fatal error: Using $this when not in object context in <filename> on line <linenumber>.
You have to instantiate the class first. Something like this:
$affiliatemarketing = new AffiliateMarketing;
and then do the following:
add_action('init', array(&$affiliatemarketing, 'initialize'), 1);
Edit: forgot to add, your action in your method should be added like this:
add_action('woocommerce_before_single_product', array(&$this, "handleAffiliateReferral"));
You're not supposed to be. That's why you're getting an error.
I don't know exactly how you're registering the method (code would help), but probably, you're expecting Wordpress to take care of creating an instance, but that's not its role.
I found thought the Codex documented if the class name is specified using its string representation, then the add_action function will assume the call is to a static method.
On the other hand if and instance of the class is passed along then add_action will use that instance to make the method call.
Although Arman hasn't specified which php version he is using, I would assume it's probably 5.3.2 or 5.3.3. The error itself is rather similar to the one described in this question and the solution also would be to upgrade to the latest version of php 5.3.
I am working on a website with php/mysql.
I have 3 files config.php, utils.php and member.php. code of the files are as below,
config.php - $objPath->docrootlibs is fine, I am sure there is no problem with this.
/* Other library files & their object */
require($objPath->docrootlibs.'/utils.php');
$objUtils = new utils();
require($objPath->docrootlibs.'/member.php');
$objMember = new member();
utils.php
class utils{
function getCurrentDateTimeForMySQL(){
return date("Y-m-d H:i:s");
}
}
members.php
class member{
var $userid;
var $username;
function __construct(){
$this->lastactivity = $objUtils->getCurrentDateTimeForMySQL();
}
}
Now when I am including the config.php inside a page home.php with simple php include statement and running that page then it gives me following error.
Notice: Undefined variable: objUtils in D:\wamp\www\site\libs\member.php on line 17
Fatal error: Call to a member function getCurrentDateTimeForMySQL() on a non-object in D:\wamp\www\site\libs\member.php on line 17
Line numbers in error above are different, I just copied the specific part from the code here.
I am not understanding why its giving error, because objects of utils class is defined on config page before including the member class. It should detect that object.
Please check and help me to understand and correct this error.
Thanks!
One Solution
Unlike JavaScript PHP will not bubble up through scopes, which means
public function __construct(){
$this->lastactivity = $objUtils->getCurrentDateTimeForMySQL();
}
does not know what $objUtils is, because there is no such object defined in the local scope. This means, you have to make the object available inside that scope. The cleanest and most maintainable way to do that is to inject the utils instance to the member instance, e.g.
public function __construct($utils){
$this->lastactivity = $utils->getCurrentDateTimeForMySQL();
}
However, since you seem to be using that value on construction only anyway, there is no reason why your member instance has to know how to use the utils object. So why not just insert the actual value right from the start, e.g.
public function __construct($lastActivity){
$this->lastactivity = $lastActivity;
}
// then do
$utils = new utils();
$member = new member($utils->getCurrentDateTimeForMySQL());
On globals
You definitely do not want to use the global keyword or static methods. Both couple back to the global scope. This means you can no longer use the member class without the global scope. This makes maintaining, reusing, refactoring and testing harder. OOP is about encapsulation and by reaching out from the class to the global scope you are breaking that encapsulation. Use Dependency Injection as shown above instead.
Apart from that, using globals will also make your code harder to read. A developer looking at the ctor signature of member is likely to assume there is nothing else to do than just call new member. That's a lie, because she also has to setup the utils instance. In other words, you are hiding dependencies. The developer has to look at the actual code to understand what's going on. Thus, make dependencies explicit.
Some more resources:
http://c2.com/cgi/wiki?GlobalVariablesAreBad
http://misko.hevery.com/code-reviewers-guide/flaw-brittle-global-state-singletons/
EDITs after comments
If you really need that utils object, inject the instance and assign it to a property inside the member instance in the ctor. Then you can access it with $this->utils->foo() from anywhere else inside the member instance.
However, Utility classes are almost always a sign of bad design. It is much more likely that they should be broken apart and divided into/onto other objects. Try to find out the reponsibilities. Maybe Member should not use Utils, but Utils should be something else that uses Members.
Out of curiosity, why do you need a utility method for MySql anyway? If you use a Timestamp column in MySql for lastActivity, it will automatically update whenever the row is updated. I am assuming you are setting the lastActivity and then store the member data?
Regarding performance: you should not bother about performance. Write readable and maintainable code first and foremost. If you think your performance is not good enough, profile the application with XDebug to see what is really making an impact.
As another comment states, use dependency injection. Insert the utilities object into the constructor. Do not introduce variables over the global scope, especially between different files. This gets very confusing and creates a mandatory order of some file includes.
class member {
...
public function __construct(utils $objUtils) {
$this->objUtils = $objUtils;
...
}
}
In calling code:
$member = new member(new utils);
As an aside, I find it humorous that you have a macro with a name that is longer than the operation it performs.
As another aside, do you need a utilities class? Can the utilities just be functions?
It sounds like config.php is in the global scope. You need to use the global keyword when using $objUtils
function __construct(){
global $objUtils;
$this->lastactivity = $objUtils->getCurrentDateTimeForMySQL();
}
Since your getCurrentDateForMySQL doesn't depend on anything else inside your utils object, why not make it a static function? That way you can turn your member() method into:
function __construct(){
$this->lastactivity = utils::getCurrentDateTimeForMySQL();
}
In my bootstrap.php I have many _initX() functions, and some of them may contain code that depends on code in the previous initX
protected function _initAutoloading() { }
protected function _initViewInitializer() { }
protected function _initVariables() { }
So my question, are these _init functions guaranteed to be executed in the exact order they've been declared?
EDIT - To provide a more direct answer to your question, I would say that they probably will be since the code uses ReflectionObjects::getmethods() or get_class_methods depending on your PHP version, so I believe those will return the function in order but there is nothing in the PHP docs or Zend docs that guarantee this will always be the case, so I would not consider this a supported feature.
You can pass the names of the resource functions you want/need to call as part of the bootstrap call: $bootstrap->bootstrap(array('foo', 'bar')); instead of not passing anything and let the Zend Application call them all automatically in which you are not sure of the order.
If you have dependencies in between your bootstrap resources however, I suggest you look at Resource plugins which will allow you to separate your code in different classes and easily call $bootstrap('foo') from within your 'bar' resource plugin code (though you can do so with the _init*() functions as well)
Another benefit of resource plugins is they can be shared with other bootstrap files if you need to and they are easier to test than _init*() functions.
Make sure you read theory of operation document from the Zend Application doc
If you really need them invoked in a particular order, you should use a helper list:
var $init_us = array(
"_initAutoloading",
"_initViewInitializer",
"_initVariables",
);
function __construct() {
foreach ($this->init_us as $fn) {
$this->{$fn}();
}
}
To use that construct in ZF you could rename the example __construct into _initOrderedList and your custom _initFunctions into _myinit... or something.
Read the manual. There are a section called Dependency Tracking :
If a resource depends on another resource, it should call bootstrap() within its code to ensure that resource has been executed. Subsequent calls to it will then be ignored.
Here is sample code :
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initRequest()
{
// Ensure the front controller is initialized
$this->bootstrap('FrontController');
// Retrieve the front controller from the bootstrap registry
$front = $this->getResource('FrontController');
$request = new Zend_Controller_Request_Http();
$request->setBaseUrl('/foo');
$front->setRequest($request);
// Ensure the request is stored in the bootstrap registry
return $request;
}
}
You don't have to rely on the order.