How do I enable code completion for clases and methods I create in code for in netbeans 8.
Thanks,
Dion
You really should google this kinda thing, but I'm in the mood to answer a question :-)
Anyway, most IDE's read your code in pretty much the same way. I can't attest to NetBeans specifically (I use PHPStorm), but the general idea is to make sure you add docblocks to your classes, methods etc. The IDE reads these and can then provide decent code-completion.
<?php
namespace App;
/**
* Class MyClass
* Does some stuff
* #package App
*/
class MyClass extends SomeOtherClass
{
/**
* This is my var
* #var string
*/
public $myVar = 'some val';
/**
* This is my method
* #param string $yourString
* #return SomethingElse
*/
public function myMethod ($yourString)
{
$this->myVar = $yourString;
return new SomethingElse($this->myVar);
}
}
Have a look at the PHPdoc site for the tag syntax. Most IDE's will also have a way of generating this for you as well.
Related
So basically I'm not sure if this is a PhpStorm issue parsing my code or if its a weird quirk of PHP and interfaces but basically I have the following interface
<?php
namespace App\Contracts;
/**
* Interface IFileSource
* #package App\Contracts
*/
interface IFileSource
{
public function getFilesByPattern(string $filePattern) : array;
}
with the following implementation
<?php
namespace App\Sources;
use App\Contracts\IFileService;
use App\Services\File\FileService;
/**
* Class FileSource
* #package App\Sources
*/
class FileSource implements IFileSource
{
/**
* #var FileService
*/
private $fileService;
public function __construct (IFileService $fileService)
{
$this->fileService = $fileService;
}
/**
* #param string $filePattern
* #return File[]
* NOTE THIS ASSUMES FILESYSTEM
*/
public function getFilesByPattern (string $filePattern) : array
{
$filesDetails = $this->fileService->getFilesByPattern($filePattern);
return [];
}
}
and the usage
<?php
namespace App\Console\Commands;
use App\Contracts\IFileSource;
use App\Sources\FileSource;
class ImportXML extends Command
{
/**
* #var FileSource
*/
protected $fileSource;
public function __construct (IFileSource $fileSource)
{
parent::__construct();
$this->fileSource = $fileSource;
}
public function handle () : void
{
$filePattern = 'APATTERN';
$files = $this->fileSource->getFilesByPattern($filePattern)
}
}
My question relates to the usage of this implementation.
So the following is a valid usage:
$filePattern = 'APATTERN';
$this->fileSource->getFilesByPattern(filePattern)
But for some reason the following is also seen as a valid usage?
$filePattern = 'APATTERN';
$this->fileSource->getFilesByPattern(filePattern,filePattern,filePattern,filePattern,filePattern,filePattern,filePattern)
Why does it not care that i am not conforming to my implementation?
Why does it not care that i am not conforming to my implementation
That's the whole point of interfaces - they don't care about implementations. They only care about how the method is defined and if the signature conforms to the interface.
However, I think the real question being asked here is why the PHP interpreter doesn't throw an exception when multiple arguments are passed to the function. The answer is because this is how PHP implements overloading. They allow a variable number of arguments to be passed which you can access with functions such as func_get_args.
You should definitely read https://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list and also look into the new(ish) splat operator ....
Similar QAs
How to pass variable number of arguments to a PHP function
https://softwareengineering.stackexchange.com/questions/165467/why-php-doesnt-support-function-overloading
So incase someone else stumbles across this,
thanks to LazyOne for the help explaining what i was doing wrong
it was due to the fact i am enforcing the implementation in the PHPdoc rather than relying on the interface to enforce the type hinting (or adding the interface as the type hint instead of the implementation), once i changed this it began complaining as expected.
Why enforce an implementation when the point of the interface is the enforce such things.
Doh
This is a question about the autocompletion behavior in PhpStorm (and possibly other IDEs) in conjunction with PHP docblocks.
I have to groups of classes in my application. First there are individual classes for various products (CarProduct, FoodProduct etc.), all inheriting from BaseProduct, and the counterpart for individual contracts (CarContract, FoodContract etc.), all inheriting from BaseContract.
<?php
class BaseContract
{
/** #var BaseProduct */
private $product;
/**
* #return BaseProduct
*/
public function getProduct()
{
return $this->product;
}
}
Now I have an instance of CarContract, and I wanna get some CarProduct specific information:
<?php
/* PhpStorm thinks, this is BaseProduct */
$product = $carContract->getProduct();
/* hence, getSpeed() is not available for PhpStorm */
$product->getSpeed();
The autocompletion is not working as I like. There are two workarounds for this, but both are not nice:
Overload getProduct() in the subclass, just with updated #return docblocks
Add /** #var CarProduct $product */ everywhere, where I access the product of a CarContract
Is there a "usual" way to solve something like this, or are my workarounds the only solutions?
PhpStorm does not really allow/does not support doing something like: have the same named class defined elsewhere and just use it as a reference for overriding definitions of real class. You can do that .. but IDE will warn with "multiple definitions of the same class" and it may introduce some weird behaviour/unexpected warnings...
Here is a ticket that ask for such feature: https://youtrack.jetbrains.com/issue/WI-851 -- watch it (star/vote/comment) to get notified on any progress.
Your options are: you can provide correct type hint locally (to local variable) using #var -- you already know it and that's first that you would think of:
<?php
/** #var \CarProduct $product */
$product = $carContract->getProduct();
$product->getSpeed();
Another possible way: instead of overriding actual method .. you can try doing the same but with #method PHPDoc -- will work with your code:
<?php
/**
* My Car Product class
*
* #method \CarProduct getProduct() Bla-bla optional description
*/
class CarContract extends BaseContract ...
I'm looking for a way to make PHPStorm hide some methods from code completion. I've tried to annotate the DocBlocks with #access private but that does not hide them from view.
Is there any way to hide private API, short of writing/generating a stub file with a limited interface and referencing that in my project?
for example:
Lets say the library has this in it:
<?php
interface IDoABunchOfStuff
{
/**
* My library users use this
*/
public function doFoo();
/**
* My Library needs this but requires that my users don't see it.
*
* #access private
* #visibility none
* #package mylib
* #internal
*/
public function doBar();
}
class Foo extends Something implements IDoABunchOfStuff
{
/**
* does foo
*/
public function doFoo()
{
// ...
}
/**
* does bar. for internal use only
*
* #access private
* #visibility none
* #package mylib
* #internal
*/
public function _doBar()
{
// ...
}
}
And my library user is typing:
<?php
myAwesomeFunction(IDoABunchOfStuff $aFoo)
{
if($->$oFoo->[CTRL+SPACE] // invoking code completion...
Is it possible to (and if it is how do I) make it so that my user never sees _doBar?
Neither of the different annotations i've tried seem to have the desired effect.
P.S. I'm using PHPStorm 4.0.3
additional:
In this case I am implementing ArrayAccess and I don't want offsetGet, offsetSet, offsetExists and offsetUnset cluttering up my code completion window but I've had similar problems elsewhere enough to warrant asking a more generalized question.
Nope -- you cannot do such thing in current version of PhpStorm.
There is a ticket on Issue Tracker that suggests using #access tag for this purpose, but currently it is not scheduled to be implemented for any particular version: http://youtrack.jetbrains.com/issue/WI-5788
Feel free to vote/comment/etc and maybe it will be implemented sooner.
I'm using PHP Storm as my IDE, but I believe that other IDE's such as Netbeans will have the same issue as I'll explain below.
When using a framework like Symfony2, we have the wonderful world of Dependency Injection added. So objects can simply be instantiated using code like the following snippet:
$myThingy = $this->get('some_cool_service');
This is very handy, as objects are already configured beforehand. The one problem is, that auto-completion breaks entirely in basically any PHP IDE, as the IDE does not know what type the get() method is returning.
Is there a way to preserve auto-completion? Would creating for example an extension of Controller be the answer? For example:
class MyController extends Controller {
/**
* #return \MyNamespace\CoolService
*/
public getSomeCoolService() {
return new CoolService();
}
}
and then for application controllers, specify MyController as the base class instead of Controller?
What about using a Factory class, or any other possible methods?
It is more involving, but you can still do this with eclipse PDT:
$myThingy = $this->get('some_cool_service');
/* #var $myThingy \MyNamespace\CoolService */
UPDATE:
The example on this page shows you may also use the other way round with phpStorm:
$myThingy = $this->get('some_cool_service');
/* #var \MyNamespace\CoolService $myThingy */
You could define private properties in your controllers
class MyController extends Controller
{
/**
* #var \Namespace\To\SomeCoolService;
*/
private $my_service;
public function myAction()
{
$this->my_service = $this->get('some_cool_service');
/**
* enjoy your autocompletion :)
*/
}
}
I use base Controller class for bundle. You need to annotate the return in method. At least that works on Eclipse.
/**
* Gets SomeCoolService
*
* #return \Namespace\To\SomeCoolService
*/
protected function getSomeCoolService()
{
return $this->get('some_cool_service');
}
I don't like /*var ... */, because it gets too much into code.
I don't like private properties, because you can wrongly assume that services are already loaded.
I use Komodo Studio, and tagging variables with #var, even inside methods, preserves auto completion for me.
namespace MyProject\MyBundle\Controller;
use Symfony\Component\DependencyInjection\ContainerAware;
use Symfony\Component\HttpFoundation\Request;
class WelcomeController extends ContainerAware
{
public function indexAction()
{
/*#var Request*/$request = $this->container->get('request');
$request->[autocomplete hint list appears here]
}
}
working with netbeans IDE 7.1.2 PHP
I've used Aptana for a good number of web projects and like it a lot. I've also used CodeIgniter for a couple projects and liked it, as well. Now I'm hoping to combine the two in a happy marriage of cross-platform productivity. Any advice on setting up Aptana's more useful features? I'm hoping to get any of the following:
Code completion
Functional built-in previewing
Debugging
If completely infeasible, what IDE would you suggest? Generic Aptana PHP setup tips would also be welcome, as they might guide me toward the ideal setup.
I would install Aptana as an Eclipse plug-in. Allows you to latter down the road install GWT or Flex with no fuss. Plus, Aptana as a plug-in has worked much better for me. Both in terms of stability and of usability.
I used to have Aptana crash on me every two days and since I'm running Eclipse with Aptana as a plug-in it never again crashed.
Eclipse with Aptana as a plug-in also has some handy features, like spell-checking, that Aptana did not have and has greatly improved my comments. That said, I must agree with you on the great level of detail and attention Aptana team has put in their software.
i have found the solution for this in codeigniter forum.
http://codeigniter.com/forums/viewthread/187641/
I came up with a slightly “safer” solution. rather than modifying the system files, create a folder called “autocomplete” (or whatever name you want)
ie
application
autocomplete
system
user_guide
then create a file (in autocomplete) called controller.php with the code below (class CI_Controller etc) . then copy this file and with the name model.php and change the class in that file to CI_Model. Aptana then uses these to remap it’s autocompletion. Just add any more functions you want autocompletion for for each file. (for instance i added CI_Cart which wasn’t in the original example in that link
(Note currently this only gives autocomplete for Models and Controllers. I guess if you’re extending other Classes and need autocompletion in those you’ll need to make a new file in the autocomplete folder with a list of all the classes that you want that class to see)
class CI_Controller {
/**
* #var CI_Config
*/
var $config;
/**
* #var CI_DB_active_record
*/
var $db;
/**
* #var CI_Email
*/
var $email;
/**
* #var CI_Form_validation
*/
var $form_validation;
/**
* #var CI_Input
*/
var $input;
/**
* #var CI_Loader
*/
var $load;
/**
* #var CI_Router
*/
var $router;
/**
* #var CI_Session
*/
var $session;
/**
* #var CI_Table
*/
var $table;
/**
* #var CI_Unit_test
*/
var $unit;
/**
* #var CI_URI
*/
var $uri;
/**
* #var CI_Pagination
*/
var $pagination;
/**
* #var CI_Cart
*/
var $cart;
}
?>