PHP - Doctrine - How to autoload entities classes using a single namespace - php

I have a group of PHP files containing classes (entities). Each class has the same namespace:
// src/App/Entity/Actions.php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Actions
*
* #ORM\Entity
*/
class Actions
{
// SOME CODE
I autoload the PHP files containing the classes with composer:
"autoload": {
"psr-0": {
"App": "src/"
}
}
And in my bootstrap.php file, I add this line:
use App\Entity;
So I figured that because told the app to use the App\Entity namespace, that I can just call the entity classes like this: $entity = new Actions();
but when I try that, I get this error:
Fatal error: Class 'Actions' not found in C:\wamp64\www\spider\chebi2\inc\orm_tools.php on line 49
If I do this:
use App\Entity; use App\Repository;
if (class_exists('Actions')) { dump('exists'); } else { dump('not exists'); }
if (class_exists('\App\Entity\Actions')) { dump('exists'); } else { dump('not exists'); }
Heres what it outputs:
PS C:\wamp64\www\spider\chebi2> php .\get_actions.php
"not exists"
"exists"
So it can only find the class when I provide the full namespace. And weirdly enough, when I tried this:
// Direct path to the Actions.php file
use App\Entity\Actions;
if (class_exists('Actions')) { dump('exists'); }
else { dump('not exists'); }
if (class_exists('\App\Entity\Actions')) { dump('exists'); }
else { dump('not exists'); }
I get the same result:
PS C:\wamp64\www\spider\chebi2> php .\get_actions.php
"not exists"
"exists"
So now I'm even more confused. What is the point in using: use App\Entity; if it doesn't actually make the classes in that namespace directly available? And why is assigning the direct path to the class use App\Entity\Actions; not even working?
Am I doing something wrong here? Is there a correct way to use namespaces that I'm not understanding?

PSR-0 is depracated you should use PSR-4
in PSR-4
composer.json
"autoload": {
"psr-4": {
"App\\": "src/",
}
}
in directory src/ which is on same level as composer.json add directory Entity so in path src/Entity add class file Actions
namespace App\Entity;
class Actions
{
}
you can also use composer dump-autoload and check vendor/composer/autoload* fiels and see if namespaces are registered there.'
Regarding class_exists() it does not work with short names or aliases you need to provide the full name of class. I'd suggest using ::class operator So in your case it would be:
<?php
use App\Entity\Actions;
class_exists(Actions::class);

Thanks! I changed the auto loader to psr-4, and attached it to this:
"psr-4": {
"App\\": "src/"
}
dump-autoload is exactly what I was looking for, but I don't see any included files or classes listed:
PS C:\wamp64\www\spider\chebi2> composer dump-autoload -vvv
Reading ./composer.json
Loading config file ./composer.json
Checked CA file C:\Users\horse\AppData\Local\Temp\composer-cacert-12fdaece071ee9515fa28aabed5ab089876ae257833106e15a583e060eaff6b5.pem: valid
Executing command (C:\wamp64\www\spider\chebi2): git branch --no-color --no-abbrev -v
Executing command (C:\wamp64\www\spider\chebi2): git describe --exact-match --tags
Executing command (C:\wamp64\www\spider\chebi2): git log --pretty="%H" -n1 HEAD
Reading C:/Users/horse/AppData/Roaming/Composer/composer.json
Loading config file C:/Users/horse/AppData/Roaming/Composer/composer.json
Reading C:\wamp64\www\spider\chebi2/vendor/composer/installed.json
Reading C:/Users/horse/AppData/Roaming/Composer/vendor/composer/installed.json
Running 1.2.2 (2016-11-03 17:43:15) with PHP 5.6.25 on Windows NT / 10.0
Generating autoload file
I still can't find the entity classes.
To clarify, I should have the folder structure like this:
- src (contains only subdirectories)
- Entity (contains the entity files)
- Repositories
- App (empty)

Related

ServiceProvider not found laravel 5.2

I'm creating a composer installable project inside vendor.
This is my service provider file,
<?php
namespace vimuths123\gitpack;
use Illuminate\Support\ServiceProvider;
class GitpackServiceProvider extends ServiceProvider {
public function register() {
$this->app->bind('gitpack', function ($app) {
return new Gitpack;
});
}
public function boot() {
// loading the routes file
require __DIR__ . '/Http/routes.php';
// define the path for the view files
$this->loadViewsFrom(__DIR__ . '/../views', 'gitpack');
}
}
This is the structure,
vendor
|
vimuths123
|-gitpack
|-src
| |-GitpackServiceProvider.php
|
|-composer.json
I already added my service provider in app/config.php
vimuths123\gitpack\GitpackServiceProvider::class,
and my root composer.json I have following code.
"psr-4": {
"App\\": "app/",
"vimuths123\\gitpack\\" : "vendor/vimuths123/gitpack/src"
}
This is my package composer file,
{
"name": "vimuths123/gitpack",
"autoload": {
"psr-4" : {
"vimuths123\\gitpack\\" : "src"
}
},
"require": {
"composer/installers": "~1.2"
}
}
but all I'm getting is this error,
Class 'vimuths123\gitpack\GitpackServiceProvider' not found
It would be great help someone can help me on this.
You should not put any files into vendor/ by hand. If you are developing a library it must be composer installable library (which once installed end up in vendor/.
Your composer.json seems wrong, especially vendor/vimuths123/gitpack/src name space in psr4. This's smells from a mile as I'd bet you not using vendor/vimuths123/gitpack/src namespace.
Finally, after adding new class you should update class loader to let it know about that:
composer dumpautoload
which solves most of problems with "cannot find my class" issues.
EDIT
It seems your problems are in your library package, not the project using it. From comments it looks that you need to edit your package's composer.json. Assuming package is using vimuths123\gitpack namespace (note, namespace does NOT have to be the same as package name - these are two different things) and its sources sit in src subfolder (so it would be <project>/vendor/vimuths123/gitpack/src) then I'd rework autoload section to look like this:
"autoload": {
"psr-4" : {
"vimuths123\\gitpack\\" : "src"
}
}
and then composer dumpautoload.
Run the following artisan command:
php artisan optimize
Then see if the class can be found by Laravel.

phpspec creates files in wrong folders per psr-4 namespace specification

I scrapped the earlier form of my question because it was too convoluted. Here's the new version.
I want to use phpspec with my psr-4 formatted projects.
Here's the way I tried to set up a test project:
Created a new folder for the project:
cd ~/Desktop/
mkdir TestPhpSpec
cd TestPhpSpec
create a new composer.json file and require phpspec:
composer require phpspec/phpspec
Which creates my composer.json file:
{
"require": {
"phpspec/phpspec": "^2.3"
}
}
I add my psr-4 namespace to the autoload property of my composer.json file:
{
"require": {
"phpspec/phpspec": "^2.3"
},
"autoload": {
"psr-4": {
"Acme\\": "src/Acme"
}
}
}
Then I dump my autoload to make sure my namespace is loaded: composer dumpautoload
After that, I create my phpspec.yml to describe the namespace to phpspec:
suites:
acme_suite:
namespace: Acme
psr4_prefix: Acme
Then I describe the class I want to start building:
phpspec describe Acme/Markdown
This is where I run into the first problem. Even though I specify the Acme namespace in my describe command, the spec does not get placed in a folder matching the namespace:
Though the class it creates is namespaced correctly:
<?php
namespace spec\Acme; // correct namespace
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MarkdownSpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType('Acme\Markdown');
}
}
Then if I try to run the test to start TDD-ing.
phpspec run
It offers to create the class for me and I let it. From there I get the second problem; I get the error message:
[PhpSpec\Process\Prerequisites\PrerequisiteFailedException]
The type Acme\Markdown was generated but could not be loaded. Do you need to configure an autoloader?
And the class it creates is not in it's namespaced folder:
The class it creates is also namespaced correctly:
<?php
namespace Acme; // correct namespace
class Markdown
{
}
I've looked over the docs and can't figure out what I'm doing wrong. Any suggestions?
Try with
suites:
acme_suite:
src_path: Acme/src
spec_path: Acme/spec

Composer autoload won't work after deployment

I am relatively new to using composer and autoload to organize my code. I have a git repository and on my local machine, I set up composer in the root dir of my project. I specified everything in a composer.json needed to get running. Using "composer install", all libraries are automatically installed.
{
"name": "my/repo",
"description": "bla",
"version": "1.2.3",
"require":
{
"php": "5.6.*",
"geraintluff/jsv4": "1.*",
"lcobucci/jwt": "^3.0"
},
"autoload":
{
"psr-4":
{
"MyNamespace\\": "src/"
}
}
}
So - once I ran "composer install" on my local machine, everything was autoloaded in my code. Fine.
But now I need to deploy the whole thing on another linux system. So i pull from the git and run composer install. All the libraries are fetched and the autoload file shows up in vendor/
Yet, I cannot use autoload (yes, I did require_once(__DIR__ . '/../vendor/autoload.php');). Everytime I try to instantiaze a class, i get a
PHP Fatal error: Class 'X' not found in /var/www/bla/x.class.php on line 123
Using use X; does not solve the problem, nor does trying to instantiate the class with its full Namespace name (e.g. $x = new \A\B\X();)
Here is the folder structure (if this matters):
+ src/
| + X.class.php // namespace here is "MyNamespace"
| + Y.class.php // same namespace
+ test/
+ run.php // namespace is "Test"
Here is a snippet of this code (run.php):
<?php namespace Test; // different namespace than the rest of the code
// making the namespace also "\MyNamespace" wouldnt work either
require_once(__DIR__ . '/../vendor/autoload.php');
use \MyNamespace\Y; // whether this line is here or not does not change the error
session_start();
// same error as with "just" implements Y {}
class SomeClass implements \MyNamespace\Y {
// ...
}
?>
So here, the Fatal error is thrown for the line where Y is extended. No matter if I use the full namespace or not. Only thing that will help is a require_once()...
So, this forces me to go back to the cumbersome way of doing all the require/includes myself!? Is there any way to solve this?
PS: composer dumpautoload wont help
PPS: composer validate shows no errors
For PSR-4 compliance, your file structure should be:
+ src/
| + X.php
| + Y.php
Note the removal of the .class.php suffix. http://www.php-fig.org/psr/psr-4/

Symfony2 composer vendor namspace not found

I'm trying to use a vendor lib that I created my self. For now I am not able to put it in GIT or SVN so I am trying to get it running without.
This is my directory structure(borrowed from an answer below):
vendor/
ISTlibraries/
Saml2Handler/
src/
Saml2Handler/
In my composer.json I have added
"autoload": {
"psr-0": {
"": "src/",
"Saml2Handler": "vendor/ISTlibraries/Saml2Handler/src/"
}
},
vendor/ISTlibraries/Saml2Handler/src/ is the path to my sourcecode. The class I am trying to get is called Saml2Controller which have this namespace defined
namespace Saml2Handler;
When I try from inside my symfony2 controller to initiate the class I get an error:
FatalErrorException: Error: Class 'Saml2Handler\Saml2Controller' not found in ...
In the controller I try a simple new Saml2Controller and I have written
use Saml2Handler\Saml2Controller;
Where am I going wrong?
The error is expected. I believe that you need the following directory structure:
vendor/
ISTlibraries/
Saml2Handler/
src/
Saml2Handler/ <--- you don't have this
Saml2Controller.php
... in order to have namespace Saml2Handler within your Saml2Handler.php.

Composer and PSR-0 class autoloading with namespaces

Hello guys i have problem with autoloading my class with composer. On Linux all work perfect, but now my boss change env and set Windows. All this work on linux but windows show newbie fatal error:
Fatal error: Class 'AbstractController' not found in
D:\xampp\htdocs\ikacFw\frontController.php on line 7
Common to see my composer.json and stucture for better picture on problem.
Stucture is :
frontController.php
-- vendor
----- Doctrine
----- Ikac
--------- Components
---------- Mvc
------------- Controller
Am trying to load all data from vendor directory.
Composer.json
{
"autoload": {
"psr-0": {
"vendor": ""
}
}
}
Also new component i add manual. Like this :
$loader = require_once 'vendor/autoload.php';
$loader->add('vendor', "Ikac");
Okay next when i try to call :
<?php
require_once 'vendor/autoload.php';
use Ikac\Mvc\Controller;
$a = new AbstractController();
I get error "not found".
My class AbstractController contain defined namespace but dont work again. Like test i do this:
<?php
//vendor/Ikac/Mvc/Controller/AbstractController.php
namespace Ikac\Mvc\Controller;
class AbstractController {
function __construct() {
echo __CLASS__;
}
}
?>
I do from cmd composer dump-autoload, install, but dont work. All this perfect work on linux but here wont. Any idea how to fix this or where i do mistake.
Thanks guys!
SLOVED:
{
"autoload": {
"psr-0": {
"": "vendor/"
}
}
}
Well you should do
<?php
require_once 'vendor/autoload.php';
use Ikac\Mvc\Controller\AbstractController;
$a = new AbstractController();
Your autoloading declaration is wrong.
You will NEVER ever need to include the vendor folder in any autoloading. The vendor folder will contain the autoloading for both all dependencies, and - if configured - for your own classes as well.
You can use Composer to create autoloading for your own classes. Just include the correct info. But from your current info I cannot deduct what would be correct.

Categories