I try to lookup the declaration of File but PhpStorm says Cannot find declaration to go to.
I also tried it with netbeans, it can't find the declartion too.
I also tried to lookup the alias use File;
I get No usage found in project files.
How does my code even know what it has to do if It can't find any declarations? This makes no sense to me.
How can I find out where File is declared?
How does my code even know what it has to do if It can't find any declarations?
By using an autoloader. This is basically a function which is called whenever an unknown class is referenced, and attempts to define it, usually by including a file according to some naming convention. You will need to find how your particular framework manages this.
Note that it's possible it's including a file from outside the directory you have set up as the "project" in your IDE. Once you've figured out where it is, you may be able to configure your IDE to know about these extra files.
How can I find out where File is declared?
Find a place where the class is used, and using a debugger or just "dump value and die", you can use ReflectionClass::getFilename() to find out about it:
$r = new \ReflectionClass(File::class);
$r->getFilename();
Note that the File::class syntax (available since PHP 5.5) gives you the fully qualified name of the class, ignoring any aliasing or namespace imports.
It's also possible for an extension (a library written in C, not PHP) to define a class. In that case, ReflectionClass::getFilename() will return false, and you'll need to use ReflectionClass::getExtensionName(), then track down the documentation for that extension.
Laravel is quite "opinionated" in the way they use facades.
Apart from the PHPStorm gudelines how to deal with it, I find artisan tinker a simplest IDE-independent way to get familiar with new codebase.
The command provides a REPL shell, so if you are curious of where the File is actually defined, just invoke it, to get some information from the error message:
>>> File::delete()
PHP warning: Missing argument 1 for Illuminate\Filesystem\Filesystem::delete(), called in /path/to/project/app/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php on line 213 and defined in /path/to/project/app/vendor/laravel/framework/src/Illuminate/Filesystem/Filesystem.php on line 118
PHPStrom scans all files in Project Root folder. Add an external library (framework) you use to Project Root folder. Maybe you should instal dependecies via composer.
Related
I develop a PHP project in Eclipse. Before updating to last version (2020-06), I used to had no warnings... Since I made this update, it is spamming me with two warnings.
First is about class files, like MyClass defined in MyClass.inc.php : Eclipse says me I must name my file "MyClass.php" or name my class MyClass.inc ... -__________- But I want to continue naming them MyClass.inc.php !!!
Second is about namespaces... I don't use them, and Eclipse says me that << The declared namespace "" does not match the expected namespace "path\folder" >> (path\folder is an exemple for this post).
I use PHP 7.4... I tried filters, but it don't work correctly (may be my bad), and I do not find how to disable this warnings specificaly.
Thanks for helping, I hope some update will fix it it if it's a bug T_T
The new namespace validation rule, although valid, is cumbersome. I guess it's nothing unusual or wrong to have namespaces which don't exactly match the directory structure.
I am working on a mezzio-based application, where this is the usual case, since the framework uses composer for autoloading.
After the upgrade there is no file in my project where Eclipse wouldn't warn that, eg.: The declared namespace "App\Middleware" does not match the expected namespace "project\src\App\src\Middleware".
This warning states the truth but by any means this case should be a reason for a warning in my opinion...
EDIT:
There seems to be an option which allows to change the reported level or to mute the "problem" completely:
Preferences->PHP->Validation->Error/Warnings: Unexpected namespace name
To configure custom paths for namespaces in Eclipse:
Install "PHP Development Tools (PDT) Composer Support"
Right click on the project → Configure → Add Composer Support
A Composer configuration dialog should open
In the "Autoloading" tab, you can assign namespaces to paths (relative to project root)
That would create a composer.json in the root of the PHP project with the following contents:
{
"name" : "my project",
"autoload" : {
"psr-4" : {
"some\\namespace" : "src/some/namespace"
}
}
}
You can define multiple mappings from namespaces to directories. See composer documentation for more information.
For your other problem, I think I would give in and move all files from .inc.php to .php. You'll probably have less problems in the future if you do so.
I wanted to test the filesystem operations of my cakephp-app using vfsStream, but had to find out that it is seemingly not possible to write files to the virtual filesystem using cakephp`s File and Folder classes. The reason for this seems to be the call to the php function realpath() in the constructor of the Folder-class. vfsStream seems to break when realpath() is used (see http://stubbles.org/categories/5-vfsStream - "realpath() still doesn't work - there is no way to make this work with how realpath() is currently implemented in PHP itself.")
It seems to be that I am out of luck or does any of you know a workaround this issue?
I am currently refactoring a project which has been halfheartedly ported to Yii. There are some classes in the components folder which are included in a controller with the PHP "use"-keyword. This gives me a "include(protected/components/classes/SClass.php): failed to open stream: No such file or directory" error though.
What's really strange about it is, that changing the name (used by "use") to a non-existent file gives me a fatal error. Any ideas?
The use keyword by itself in PHP does not do any including of other files. It merely tells PHP that the namespace defined in the use statement may be referenced by code further down in the current PHP file.
However, what is likely happening here is that your system has an autoload function defined. If there is an autoload function, PHP will call this function whenever it encounters a class name that it doesn't recognise. The autoload function searches for the class file to load and includes it if it can find it. This is probably where your errors are occurring.
In the first case, this is the sequence of events:
the use statement is referencing a valid namespace, but this is ignored until a class in that namespace is referenced in the code.
When the class is referenced, PHP says "I don't know this class yet, lets autoload it".
The autoloader function is run, and builds a path to include. This usually comes from the namespace and classname of the class, but can be whatever the autoload function is written to expect.
In this case, it sounds like the autoloader is building the path and running include() on that path, but the class doesn't exist where the autoloader expects. Hence the "file not found" error.
In the second case, where you change the use statement:
The use statement now references a different namespace, but you probably haven't changed the code later in the program that actually references the class.
The program reaches the code that calls the class, but it doesn't recognise the namespace because it doesn't match the use statement any more, so instant fatal error.
You might want to check the file ownership and permissions, and check for PHP security as is mentioned HERE
Let's say i have this php function called from multiple php files
do_something($var);
How can i find the files from which the function is called?
later edit: i want to do this on windows
At least some IDE's have a means of searching through your current project for all instances of certain variables, function calls, etc. If you are using an IDE, check its help.
If you are using a *nix system, you can use grep to search:
grep do_something *.php'
The above will search your current working directory for the text 'do_something' in all files ending with the '.php' extension. You can expand this to search all subdirectories of the current directory using the find command:
find . -name "*.php" -exec grep do_something {} \;
Use 'man grep' and 'man find' from your *nix command line to learn more.
If you are on Windows, I believe the find command can do similar things, I am not as familiar with it, but the basic syntax should look something like:
find "do_something" *.php
Three ways to do this:
Use a sensible directory structure and application design. If you're following OOD and have a clearly laid out directory structure, then it should be very easy to find the declaration for any class and its methods. If the method was declared in a parent class, you just scan up the inheritance tree. If, OTOH, you're writing spaghetti code and using tons of global functions, well... you've got bigger problems.
Consult the documentation. Any sizable application should have a well-documented API, which at minimum should include a list of all classes and their member functions and attributes. The API documentation should also tell you the file that each class is defined in. A quick search in the API would thus turn up the info you need.
Use an intelligent IDE like Eclipse that parses your code and class definitions. Eclipse has an Open Declaration function that will open up the source file where the element was declared and display the declaration.
You should always be doing the first two; the last is just a convenience.
Adobe Dreamweaver has a site wide/directory text search function as does eclipse workbench, UltraEdit and TopStyle Pro.
I'm migrating a php application from procedural to oop.
I use a DEBUG constant to activate errors and warnings output (in fact, I have thee, every one makes the output more verbose.
But I can't find a way to access those constants from within a method.
The constants are defined before autoload in a separate file.
In the utility file I have
define('DEBUG', TRUE);
And inside a given method I tried to
if(!defined('DEBUG')) define('DEBUG', FALSE);
But I always end up with DEBUG=FALSE.
What am I doing wrong? I'm a total noob to oop, so be gentle please :-)
Clarification
Every class has his own file.
In any given script, the first thing I do is to include the utility file. The utility file is the one who defines DEBUG and has the _autoload function.
script_file.php
includes utility_file.php
defines DEBUG
has _autoload function
according to this, you should access DEBUG (no prepending $) in your code directly. are you including or requiring your utility file in the same file that has the function you're talking about? i don't think this is an OOP problem
darkphoenix was right, This wasn't an OOP problem. This was a NetBeans problem.
I'm using NetBeand and uploading the files to a remote server upon save. I've set the DEBUG constant to TRUE in the utility file and hit save on NetBeans, the save process (apparently) went without problems (no warnings or anything).
Big was my surprise when latter I logged in via SSH did a cat on the file. The file was never saved to the server. My local copy has my last edit, but the remote one doesn't...
Moral of the story: I hate you NetBeans