I have a project in laravel and I am trying to move all of my source files to app/src/{module}. I am autoloading the directory in composer.json.
I am having to declare/import all of the global classes from laravel in my files under src/. For example if I want to use Input I have to say use Input;. How can I access these classes as if the file was in the app/controllers directory?
What I added to composer.json:
"autoload": {
"psr-0": {"Illuminate\\Auth": ""}
},
The top of one of my files under src:
<?php namespace src\proposal;
use Input,JsonResponder,Request,JsonValidator,DB;
class ProposalRepo implements IProposal
{
Just because you are using your own namespaces, you will need to either use global classes like \Input::get() or you will need to put use Input; to the top of your file. At least this is how i solve this issue.
Related
I'm a bit confused because I'm programming a plugin for WordPress by using composer as it's the real way to go.
So I've created a composer file inside my plugin and some other stuff. In the composer file I've added my namespace for autoloading:
"autoload": {
"psr-4": {
"Johnny\\Lolkick\\": [
"includes/classes/"
]
}
}
Inside my classes folder I've created now a class with the name class-main.php. I've decided to take this name because of the WordPress naming conventions:
https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#naming-conventions
The class by itself was named class Main {. Inside my base plugin file I've created now a new instance of my class which failed. After changing the file name to Main.php it worked.
So in result the WordPress naming convention broke the autoloading of composer. I want to know now how do you handle this problem? How should I keep the naming convention by using composer?
Since your code base is not compatible with PSR-4 autoloading, a psr-4 mapping inside your composer.json's autoload section won't work, as you noticed.
I'd say you have two choices here:
First one would be to use classmap instead:
{
"autoload": {
"classmap": ["includes/classes/"]
}
}
This would simply parse all the files recursively within that folder and map the classes to their names, no matter what naming scheme you're following.
Second one would be to build your own autoloader, and use files to have it loaded automatically:
{
"autoload": {
"files": ["includes/autoloader.php"]
}
}
That autoloader would have to define what should happen (which class should be loaded, or not) when referring to a given class name.
In both cases, don't forget to run composer dump-autoload afterward.
In my default symfony4 structure I want to add lib folder, where I have additional classes. So something like this:
-bin
-config
-lib
- Importer.php
...(other files with classes)
-public
-src
- Controller
- TestController.php
- Entity
- Form
...
...
But I cannot figure out how to later use my files (i.e.: Importer.php).
Let's say Importer.php has a single class Importer() inside. If I try to use it from TestController.php I get:
Attempted to load class "Importer" from namespace "lib". Did you
forget a "use" statement for another namespace?
TestController.php has
use Importer;
specified on top (autodetected by PhpStorm). I also tried adding namespace in my Importer.php file, for example:
namespace lib;
and then in TestController:
use lib\Importer;
But it produces the same result.
Lastly after reading about services, I tried adding the file to config/services.yaml
lib\:
resource: '../lib/Importer.php'
Which gives the same result...
What to do, how to live?
First of all read about php namespaces.
Next read about the psr-4 standart.
Select a prefix for your folder, let's say Lib. Make sure that all files in the lib folder has a properly namespace. E.g. Importer class must be stored in the lib\Importer.php and must have the namespace Lib;, Items\Item class must be stored in the lib\Items\Item.php and must have the namespace Lib\Items\Item; and so on.
Your files are ready. Just need to inform Symfony about them.
Symfony uses composer's autoloader, so check composer's autoload section. Than add new folder for autoloading in composer.json:
"autoload": {
"psr-4": {
"App\\": "src/",
"Lib\\": "lib/"
}
},
It says that all classes in lib folder have their own separate files and Lib prefix in their namespace and other part of namespace is similar to directories structure.
Next you need to clear autoloader's cache. Run in console:
composer dump-autoload
And finally you can use your class:
use Lib\Importer;
$importer = new Importer;
Also you can add your files to autowire.
In my project I have a folder lib\custom which contains Web folder and functions.php file. In my functions.php I have some functions which I need to use in another classes and in this file on the first line I have a defined namespace look like this
<?php
namespace Custom;
function abc(){....}
And in Web folder I have some classes with namespace Custom\Web;
In my composer.json file I have defined namespace look like this
"Custom\\":"lib/custom/"
So , now I am using the abc() look like this
use Custom;
$abc = Custom\abc("abc")
but as a response I am getting
Call to undefined function Custom\abc()
How can I solve this problem?
PSR-4 describes a specification for autoloading classes from file paths. It doesn't cover loading functions from files.
Use the files autoloader to load a file with functions on each request automatically. This will make your function available as long as you included the autoloader:
{
"autoload": {
"files": ["lib/custom/functions.php"]
}
}
Since your functions are namespaced you'll need to import them with the use statement or use the fully qualified name.
If your Web folder contains PSR-4 compatible classes, load them as before with the PSR-4 autoloader (you can define multiple autoloaders in your composer.json).
I'm working with Laravel framework.
I have a question regarding classes creation.
To explain my question, i will give you an example:
class articleController extends Controller{
public function bla(){
$a = new MyNewClass($colorfulVariable);
$b = $a->createSomething(new MySecondNewClass());
}
}
Now, the classes MyNewClass and MySecondNewClass do not exist, I want to create them, use them in every controller I want, just like I use the Redirect or Request classes that Laravel offers.
How can i create this classes? Make a new functions to use them in my laravel project?
you can just create those classes in your app folder (or in subfolder for example we create a Libraries folder with all the utilities). Just include a use App\YourClass; before using those classes and laravel will include the classes for you
Laravel 5.* is autoloaded using PSR-4, within the app/ directory. You can see this in the composer.json file.
"autoload": {
"classmap": [
"database/seeds",
"database/factories"
],
"psr-4": {
"App\\": "app/"
}
},
Basically, you could create another directory within app, and then namespace your files in there as appropriate:
app/folder1/folder2/SomeClass.php.
Then, within your SomeClass.php, make sure you namespace it:
<?php namespace App\folder1\folder2;
class Someclass {}
Now, you can access this class using the namespace within your classes:
use App\folder1\folder2\SomeClass;
You can create your classes as usual, but don't forget to include them into composer.json autoload section:
"autoload": {
"classmap": [
"App\MyClassesNamespace"
....
And then run composer dumpauto command to rebuild autoloader file. If you'll not do this, you'll not be able to use your classes in your application.
You don't have to do anything other than below things:
Create a class in App\ folder.
Whenever you use the class, you will have to import the class using "use App\XYZ;" on top of the importing class.
thats it. Mostly people follow convention and then create "Service" folder on App\ folder. It is good to create alien class into service folder which are other than laravel framework classes.
I'm kind of confused on how to load my own code (classes or just regular functions) into a Laravel app. I've seen this done in several ways:
Creating a folder inside the app directory (for example: app/libs) and add app_path().'/libs' to start/global.php
Add it into composer.json's "require"
Add "psr-0" into composer.json's "autoload" and add there the files
Add a My\Custom\Service\Provider into app/config/app.php's 'providers' and the alias for the facade
What's the difference between them? Why and when should I use any of those ways? Should I load a class, several .php files or simply the folder? Maybe reference those 3 things at the same time?
EDIT:
These are my guesses:
Option 2 is just for packages
Option 3 if you want to load every class inside a custom namespace declared within the new created folder (don't get why the "psr-0" instead of just adding it to "classmap")
Option 1 is the same as option 3, just handled by Laravel instead of Composer
You can reference a folder and it will load every class found inside, or you can reference a certain file and it will load the class found inside
About option 4:
If you want to use the facade anywhere on your code, and that will need the namespace added into composer.json
EDIT 2:
If you add them to "classmap":
"classmap": [
"app/libs"
]
every class from any namespace within files inside the app/libs folder, will be loaded
If you add them to "psr-0":
"psr-0": {
"Libs": "app/"
}
it will load every class within the Libs namespace inside the app/libs folder
Still not sure why/when to use service providers and aliases.
EDIT 3:
"psr-0" if I want to load a namespace that follows a folder structure (it won't load a class within a subnamespace if it doesn't match the folder structure)
"classmap" for "random" classes, functions... sort of "the rest"
you can load your own code 2 (maybe 3) ways in laravel.
use composer
use ClassLoader
Manual include or require anywhere
Option 2 is just for packages
yes, you're right.
Option 1 is the same as option 3, just handled by Laravel instead of
Composer
yes, you're right.
Option 3 if you want to load every class inside a custom namespace
declared within the new created folder (don't get why the "psr-0"
instead of just adding it to "classmap")
some packages or classes adhere psr-0 standard, the rest is not. psr-0 option is mapping namespace to directory. the classmap is mapping
the namespace to certain directory or file and used for the class that is not adhere psr-0 standard.
You can use the classmap generation support to define autoloading for all libraries that do not follow PSR-0/4.
If you want to use the facade anywhere on your code, and that will
need the namespace added into composer.json
nope, instead, you have to add class alias for the facade in app/config/app.php
if your code is just file, not a class, then use composer autoload files
if your code is class but not adhere psr-0/4 standard, use composer autoload classmap or just add the containing directory to app/start/global.php.
otherwise, use composer autoload psr-0 or psr-4.
in Laravel 4,I add all of my class in "mylibrary" folder.
Then at app/start/global.php , I add app_path().'/mylibrary',
ClassLoader::addDirectories(array(
app_path().'/commands',
app_path().'/controllers',
app_path().'/models',
app_path().'/database/seeds',
app_path().'/mylibrary',
));
Within mylibrary there is MyClass.php , within MyClass.php there is test_myfunction()
and at app/view/home.blade.php I add these code :
<?php
$FMyClass11 = new MyClass;
$just_test=($FMyClass1->test_myfunction());
?>
Hope it works for you. :)