I am really new to symfony but a long year developer. Now I decided to look at symfony but as it is with new things, problems aint far :)
I want to include a class into my project. Everytime I create a instanec of the class
$fw = new FloydWarshall($graph, $nodes);
i'll receive an internal error 500.
What am I doing wrong ?
Structure:
app/
...
bin/
...
src/AppBundle/
Controller/MyController.php
Entity/
...
Model/
fw.class.php
Reposetory/
...
var/
...
vendor/
...
web/
...
So in my class the namespace looks like
namespace AppBundle\Controller;
use AppBundle\Entity\lpNodes;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use AppBundle\Model\FloydWarshall;
....
In my fw.class.php the header looks like:
<?php
/**
* #package FloydWarshall
* #author Janne Mikkonen <janne dot mikkonen at julmajanne dot com>
* #date $Date: 2013/03/23 05:10:48 $
* #version $Revision: 1.1.1 $
* #license GNU General Public License, version 2 http://www.opensource.org/licenses/GPL-2.0
**/
namespace AppBundle\Model;
class FloydWarshall {
the constructor of FloydWarshall:
/**
* Constructor
* #param array $graph Graph matrice.
* #param array $nodenames Node names as an array.
*/
public function __construct($graph, $nodenames='') {
$this->weights = $graph;
$this->nodes = count($this->weights);
if ( ! empty($nodenames) && $this->nodes == count($nodenames) ) {
$this->nodenames = $nodenames;
}
$this->__floydwarshall();
}
As per comment, Symfony 3 uses either PSR-0 or PSR-4. Assuming that you're using Composer, you configure which one to support in your composer.json file.
With PSR-4, your filenames must correspond to your class names, and your directory names must match your namespaces. So if your entity is called FloydWarshall in the namespace AppBundle\Entity:
it must be in the directory src/AppBundle/Entity
the file must be called FloydWarshall.php
The reason for this strictness is the autoloader which comes with Composer. When you do new AppBundle\Entity\FloydWarshall, the autoloader knows where to find the file for that class. In your case, you had named it fw.class.php so the autoloader couldn't find it.
Tangentially to the question, are you using the dev environment? If you are, Symfony will give you a very helpful error message which will help you to diagnose the problem much quicker.
Related
I am having a lot of trouble getting PHPStan to see the FuelPHP core classes. It would appear this sort of thing causes it grief:
namespace Fuel\Core;
/**
* Template Controller class
*
* A base controller for easily creating templated output.
*
* #package Fuel
* #category Core
* #author Fuel Development Team
*/
abstract class Controller_Template extends \Controller
{
/**
* #var string page template
*/
public $template = 'template';
Where Controller is also in the Fuel\Core namespace:
namespace Fuel\Core;
abstract class Controller
{
/**
* #var Request The current Request object
*/
public $request;
It looks like PHPStan can's find Controller because it is looking in the root namespace. FuelPHP gets around this (magic? autoloading? aliasing?). Is there a way to get PHPStan to jump on the same bandwagon, or do I need to stub out all the core classes I'm using?
Did you try to follow this guide? PHPStan: Discovering symbols
I helped set up FuelCMS analysis in the past. What worked for that user was this phpstan.neon:
parameters:
scanDirectories:
- core/classes
bootstrapFiles:
- core/classes/autoloader.php
There's an example repository that works: https://github.com/ondrejmirtes/phpstan_problem/tree/fix
For some reason the phpstan.neon is buried in app/classes/controller while it should definitely be in the root directory. But otherwise it works.
I have following problem: I have class Router (in project/connection/api/callbacks) and TestRouter (in project/tests/api).
Class Router is only Example and I don't want psr-0 or 4.
Router has this code on the beginning:
<?php
namespace Connection\Api\Callbacks;
class Router
{
Test class start with this code:
<?php
$loader = require __DIR__ . '/../../vendor/autoload.php';
$loader->add('Connection\\Api\\Callbacks', __DIR__ . '/../../connection/api/callbacks');
class TestRouter extends PHPUnit_Framework_TestCase
{
function test() {
$variable = new \Connection\Api\Callbacks\Router();
}
Then I got error class not found. Please where is the problem?
You don't want PSR-0, but you are using exactly that function. The code comment for the add() method you are using to add your class to the autoloader:
/**
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* #param string $prefix The prefix
* #param array|string $paths The PSR-0 root directories
* #param bool $prepend Whether to prepend the directories
*/
public function add($prefix, $paths, $prepend = false)
I wonder what keeps you from simply using PSR-4 in this case. Just add the necessary declaration to your composer.json file.
When it comes to PHPUnit, add require "vendor/autoload.php" to the bootstrap file or use it as the full bootstrap file if you don't have to do anything else there. It will make writing tests easier because you don't have to take care of the autoloading and adding the individual class to the autoloader. Also, you won't end up instantiating multiple autoloaders that don't get removed from the autoloader stack.
I have a Symfony project to which I added some non-symfony php files containing various classes. But for some reason the classes are not loaded when loading the website, even though the IDE sees them properly.
So, I have a class that needs other classes:
namespace rootspace\FrontBundle\Controller;
use rootspace\FrontBundle\Networks\TwitterOAuth;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
class TwitterController extends Controller
{
public function connectAction(){
// The TwitterOAuth instance
$connection = new TwitterOAuth('abc', '123');
}
}
And then the class which fails to load (that needs yet another file)
namespace rootspace\FrontBundle\Networks;
/* Load OAuth lib. You can find it at http://oauth.net */
//require_once('OAuth.php'); -- should this be commented out?
/**
* Twitter OAuth class
*/
class TwitterOAuth {
/* Contains the last HTTP status code returned. */
}
Lastly, the third file
namespace rootspace\FrontBundle\Networks;
use Symfony\Component\Config\Definition\Exception\Exception;
class OAuthConsumer
{
public $key;
public $secret;
}
(...)
I assume the actual filenames don't matter, right? Nor their structure? PhpStorm sees all the classes properly, I can right-click through them, but it fails when deployed.
Thanks for help
Edit - the whole error message says
Attempted to load class "TwitterOAuth" from namespace "rootspace\FrontBundle\Networks" in D:\Dropbox\project\src\rootspace\FrontBundle\Controller\TwitterController.php line 15. Do you need to "use" it from another namespace?
This is because Symfony's autoloader follows PSR standards (PSR-0, PSR-4) which says that fully qualified (with namespace) class name translates to file location and name. So in fact file names does matter.
So in your case rootspace\FrontBundle\Networks\TwitterOAuth class should be located in rootspace/FrontBundle/Networks directory in file called TwitterOAuth.php
If classes you are using does not follow PSR standards you can also register them manually in app/autoloader.php file
Check these for more info:
How can I add a namespace to Symfony 2.1?:
How to autoload class
And check this answer
I forgot to add a .php extension to my filename
I am trying to use ExclusionPolicy however I keep getting an "Annotation does not exist, or could not be auto-loaded" error.
Here is the exact error being thrown out:
[Semantical Error] The annotation
"#JMS\SerializerBundle\Annotation\ExclusionPolicy" in class
Acme\DemoBundle\Entity\Attributes does not exist, or could not be
auto-loaded.
My code is as follows:
namespace Acme\DemoBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints;
use JMS\SerializerBundle\Annotation\ExclusionPolicy;
use JMS\SerializerBundle\Annotation\Expose;
/**
* Acme\DemoBundle\Entity\Attributes
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="Acme\DemoBundle\Entity\AttributesRepository")
*
* #ExclusionPolicy("all")
*/
class Attributes
{
...
}
your problem is caused by using the wrong namespace.
Instead of:
use JMS\SerializerBundle\Annotation\ExclusionPolicy;
use JMS\SerializerBundle\Annotation\Expose;
It should be:
use JMS\Serializer\Annotation\ExclusionPolicy;
use JMS\Serializer\Annotation\Expose;
Notice "Bundle" is gone. In Ver 0.11 it was extracted to its own repository.
The changelog is as follows:
Namespace Changes
The core library has been extracted to a dedicated repository
schmittjoh/serializer to make it easier re-usable in any kind of PHP
project, not only in Symfony2 projects. This results in several
namespace changes. You can adjust your projects by performing these
replacements (in order):
JMS\SerializerBundle\Serializer -> JMS\Serializer
JMS\SerializerBundle -> JMS\Serializer
JMS\Serializer\DependencyInjection -> JMS\SerializerBundle\DependencyInjection
Dependency Changes
You might need to increase versions of jms/di-extra-bundle, and also
jms/security-extra-bundle depending on your stability settings.
Sometimes it is also necessary to run a composer update twice because
of a bug in composer's solving algorithm.
Is it good practice to include namespaces for classes in #param annotations? I know that phpdoc does not support namespaces, but how will other tools like phpdox or Doxygen act?
Which way is better / more common?
namespace foo\someNamespace;
use foo\someOtherNamespace\MyOtherClass;
--- with namespace ---
/**
* #param \foo\someOtherNamespace\MyOtherClass $otherClass
*/
class myClass(MyOtherClass $otherClass)
{
// do something
}
--- without namespace ---
/**
* #param MyOtherClass $otherClass
*/
class myClass(MyOtherClass $otherClass)
{
// do something
}
The namespace is a part of the complete name of the class. So if you wouldn't add the namespace to the classname in #param you would give a wrong type.
Personally I think namespaces will become very soon the main criteria for the organization of classes in PHP. So the documentation tools will all have to use them.