How can we have autocomplete on property when this one isn't define in the same php file.
for example, with ZF, in the controller we can do
$this->view->voiture = new My_Voiture();
and in the view, we have a variable $this->voiture, but how can i have the autocomplete on it ?
i try /* #var $this->voiture My_voiture */ and no result...
for the moment, my answer is to do in the view
/* #var $voiture My_Voiture */
$voiture = $this->voiture;
but i don't like it. Have you better ?
Documenting the original variable in its original source is actually the best way to go, I think. All other usages of your view in other files should inherit the autocompletion just by documenting it at its one source.
In order to get the autocompletion that I would expect, I would do these things:
In the My_Voiture class, make sure you have docblocks for your variables and your methods. This isn't technically necessary for the autocompletion itself, but it will allow the autocompletion popups to contain much more info that just variables and methods.
In the My_View class, where $voiture is first declared (not used), I would place the #var docblock that identifies its type as My_Voiture. This should be enough to make any usage of its $voiture variable inherit the properties of My_Voiture.
In the My_Controller class, where $view is first declared (not used), I would place the #var docblock that identifies its type as My_View. This should be enough to make any usage of its $view variable inherit the properties of My_View.
Now, in your code file where you are expecting autocompletion on $this->view->voiture -- if it has nothing in it that indicates that $this is a My_Controller object, then Eclipse has nowhere to start when it tries to identify $this (and then all of its properties). I think I've seen some MVC code before where this is prevalent, due to much "dynamic" properties relying on "variable variables" like $$foo.
Related
I'm developing an application with Yii 1.1 using the "PHPStorm" IDE (version 8.0.2). While it manages to find declarations of base Yii methods, it can't find implementations of methods declared in models of the application.
When I try to click on a function and choose "Go To... Implementations" in the context menu, they can not be discovered.
One of the examples:
I rightclick on a method implementation in a view and choose "go to the declaration". The IDE manages to correctly direct me to the method declaration in a model. At the same time, when I try to find implementations of the exact same method, the IDE fails to find them.
Am I doing something wrong?
I'm using NetBeans and as far as I know the Go to declaration depends on two things 1) to have added the framework files to project includes in case the files are outside 2) go to declaration will work based on the way you define the variables, and some of them might not work at all in case of magical methods.
But you could always declare the class of a variable by using some comments, for example:
$post=Post::model()->find();
$post->save();
If I click on save() might not work depending on what ::model() and find() return. But I could declare $post as Post with a comment:
/* #var $post Post */
That will let the IDE know that $post is of type Post. Then based on that it will know that it extends CActiveRecord and so it will locate the save() method and go to declaration will work.
Always make sure that either:
functions return a instanciated object, ej: $post=Post;
if not, at least specify in #return comment what type of object they return
and lastly if none of them, you can always use the commenting way above
I want to research the source code of pyrocms, and when I read the Base.php, I can't understand the following code
new CI;
the file is system/cms/libraries/Base.php
My problems are
why there has no a variable name, like $CI = new CI;
why it can be used as CI::$APP->config->item('controller_suffix') in it's sub class MX_Controller since there does not have variable name?
Thank you very much!!!
This object isn't stored in a variable because it seems we don't need to manipulate it. On the other hand, look at its constructor: it does a lot of things (since it also calls the constructor of CI_Controller, which in turns loads a Loader and initializer it, ....)
So, we don't build it in order to manipulate it afterwards, but in order to run the code in its constructor.
We can use CI::$APP-> whatever because $APP is a static member, hence it doesn't require to have an instance of CI to be manipulated
Declaring class properties or methods as static makes them accessible without needing an instantiation of the class. A property declared as static cannot be accessed with an instantiated class object (though a static method can).
see statics on php.net
I am making usage of
/* #var $var Type */
really often for NetBeans can then autocomplete methods and stuff in code.
Still I think its a very useful feature but sometimes I got objects of
classes extending one more class and implementing multiple interfaces.
Or I even got a transitive class hierarchy.
I don't know a way to tell NetBeans that it shall be using autocomplete for
all these interfaces and upper-layer parent classes.
I would like to do so for of course every of these interfaces / classes got
dedicated methods (which are defined somewhere in case of interfaces...)
I tried something like this:
/* #var $var TypeA|\TypeB|\TypeC */
because I saw NetBeans will generate a similar documentation for methods returning
different class objects due a switch/case. But this seems to work only for the
#return notation.
I also tried
/* #var $var TypeA|TypeB */
Also not working...
NetBeans will autocomplete the last told Type in this case but not a combination of both/all told classes.
How can I document so my autocomplete works as desired (a summary of methods of all classes /interfaces I listed)?
regards!
If I understand you correctly, you are asking to chain hint through your PHP code.
The problem is netbeans has no way of knowing what an object actually is; unless you tell it. The solution is to use the #property command in your object decleration to forward type define the objects members , be it a class or interface.
/**
#property classMyClass1 $clsMyClass1
#property classMyClass2 $clsMyClass2
*/
class baseClass{
public $clsMyclass1;
public $clsMyClass2;
public function __construct() {
$this->clsMyClass1 = new classMyClass1();
$this->clsMyClass2 = new classMyClass2();
}
}
$foo = new baseClass();
Now when you type your code in netbeans it will know what hinting to display on your last typed object
$foo->clsMyClass1->
So long as each class has a forward property decleration you can chain as long as you want
$foo->class1->class2->class3->...
The above code would need the autoload() function to load the correct class files....
Hope this helps you!
I am doing a class "Container" to hold all my model/service instances, the class is a singleton.
Consider the following code portion (from a CodeIgniter project):
public function getReviewModel()
{
static $loaded = false;
if (!$loaded)
{
$this->load->model('review_model');
$loaded = true;
}
return $this->review_model;
}
I am wondering if is still ok to use static inside method like this or should I use only class property (I mean about performance and coding standard) ?
In your example, nothing prevents the programmer to instanciate the class more than once (with dire results), so it is rather a confusing bit of code.
Static variables have their uses, be them local to a function or defined at class level.
Especially in PHP scripts, when the output is often a single piece of data that can conveniently be handled as a class defining only static properties and methods.
That would be a true, foolproof singleton class.
Since mistaking a static variable for a dynamic one is a common pitfall, I tend to favor static class variables to avoid the confusion (i.e. the self::$... syntax makes them stand out clearly).
General consensus as far as statics are concerned in PHP is: Avoid, if at all possible. And yes, 99% of the time, it is possible to avoid statics.
Singletons should be avoided 100% of the time. For reasons you can find here and virtually everywhere else on the web. Singletons are like communism: sounds like a nice idea, but when put in to practice, it turns out there's one or two things you didn't anticipate.
A Singletons' main purpouse is to retain state, but PHP itself is stateless, so come the next request, the singleton needs to be re-initialized anyway.
If I write getters like yours, I tend to create them in a lazy-load kind of way:
class Example
{
private $reviewModel = null;//create property
public function getReviewModel()
{
if ($this->reviewModel === null)
{//load once the method is called, the first time
$this->reviewModel = $this->load->model('review_model');
}
return $this->reviewModel;
}
}
This basically does the same thing, without using statics. Because I'm using a property, I still retain the instance, so if the getReviewModel method is called again, the load->model call is skipped, just as it would be using a static.
However, since you're asking about performance as well as coding standards: statics are marginally slower than instance properties: Each instance has a HashTable containing for its properties, and a pointer to its definition. Statics reside in the latter, because they are shared by all instances, therefore a static property requires extra lookup work:
instance -> HashTable -> property
instance -> definition -> HashTable -> property
This isn't the full story, check answer + links here, but basically: the route to a static propery is longer.
As for coding standards: They exist, though still unofficial, most major players subscribe to them, and so should you: PHP-FIG
Things like $this->_protectedProperty; don't comply with the PSR-2 standard, for example, which states, quite unequivocally:
Property names SHOULD NOT be prefixed with a single underscore to indicate protected or private visibility.
I am creating my own MVC framework, and I want it to be very basic, but when I use some IDE's like Eclipse or NetBeans they tend to give me warnings telling that those variables where not initialized or they do not recognize what type they are, so they do not autocomplete the class methods or properties the variable supposed to be of.
To override this, I created a PHP file where the the global environment variable is set and a new object is instantiated and then destroyed, so the IDE recognizes it and I can work with it well.
But then these classes constructors execute at that time, and it could be dangerous and even slow down my code. So, to override this better, how could I define a variable type to be of a specific class, without instantiate it?
Like in Delphi we do var Test = TTest; and in Java we do String testString; before testString = new String;
Depending on the IDE, you can use PHPDoc comments to get code completion
/** #var YourClass */
private $variable;
This is IDE specific though
Edit and 6 years later (almost to the day), with the advent of php 7.4, you can now declare types for class properties:
Class SomeClass
{
private YourClass $variable;
public string $something_else;
}
PHP is loosely typed, so you can't do it like you do in Java. You can provide type hinting for custom classes, though. See this description on PHP.net: http://php.net/manual/en/language.oop5.typehinting.php
I know now that Facebook developers created a PHP variant called Hack, which is a PHP with strong types.
Type declarations can be added to function arguments, return values, and, as of PHP 7.4.0, class properties.
Off course not for all php versions!
see more