What is wrong with this use of Silex' autoloader? - php

My application file:
<?php // /src/app.php
require_once __DIR__ . '/../lib/vendor/Sensio/silex.phar';
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Foo\Bar;
$app = new Silex\Application();
$app['autoloader']->registerNamespace('Foo', __DIR__);
$bar = new Bar();
(...)
My Bar class:
<?php /src/Bar.php
namespace Foo;
use Silex\Application;
use Silex\ControllerProviderInterface;
use Silex\ControllerCollection;
use Symfony\Component\HttpFoundation\Response;
class Bar implements ControllerProviderInterface { ... }
When I do a $bar = new Bar() in my app.php, I get an error: Fatal error: Class 'Moken\Classname' not found in (...)/src/app.php on line 11
Can anyone tell me what I am doing wrong?

If you use namespace Foo; you must locate this class in Foo directory
Every namespace part is a directory in symfony
If not works, you must show the loader where to find this class
In symfony2 I use for this:
use Symfony\Component\ClassLoader\UniversalClassLoader;
$loader = new UniversalClassLoader();
$loader->registerNamespaces(array(
// HERE LOCATED FRAMEWORK SPECIFIED PATHS
// app namespaces
'Foo' => __DIR__ . '/../src',
));

In your main php file (index.php) you must:
declare the use of your Controller Provider;
after creation of your Application object you must register your namespace;
mount your Controller Provider.
For example (Example\Controllers is the namespace and XyzControllerProvider is the Controller Provider, the url is /my/example):
[...]
// declare the use of your Controller Provider
use Example\Controllers\XyzControllerProvider;
[...]
//after creation of your Application object you must register your namespace;
$app = Application();
$app['autoloader']->registerNamespace('Example', __DIR__.'/src');
[...]
//mount your Controller Provider
$app->mount('/my/example', new Example\Controllers\XyzControllerProvider());
the Controller Provider (under src/example/controllers) will be:
<?php
namespace Example\Controllers;
use Silex\Application;
use Silex\ControllerProviderInterface;
use Silex\ControllerCollection;
class XyzControllerProvider implements ControllerProviderInterface {
public function connect(Application $app) {
$controllers = new ControllerCollection();
$controllers->get('/', function (Application $app) {
return "DONE;"
});
return $controllers;
}
}

Related

Correct way to reference class\method in another file

I have class that I have set up like this:
use MVC\Model;
use \Firebase\JWT\JWT;
class ModelsAuth extends Model {
In my ModelsAuth class, I have this member function:
public function validateToken($token) {
}
I am using this to autoload my classes:
// autoload class
function autoload($class) {
// set file class
$file = SYSTEM . str_replace('\\', '/', $class) . '.php';
if (file_exists($file))
require_once $file;
else
throw new Exception(sprintf('Class { %s } Not Found!', $class));
}
// set autoload function
spl_autoload_register('autoload');
Is it possible to call this class and function from outside the class?
I have tried:
$authorization = new \MVC\Model\ModelsAuth();
$authorization->validateToken($token);
and
$authorization = MVC\Model\ModelsAuth::validateToken($token);
Both return a class not found error.
Any thoughts on what I might be doing wrong with this approach?
You have not declared a namespace for your class, so it's not clear that it will exist as MVC\Model\ModelsAuth and it's probably just going into the root namespace as \ModelsAuth. You probably want something like this:
namespace MVC\Model;
class ModelsAuth extends \MVC\Model {
...
}
Which can also be specified as:
namespace MVC\Model;
use MVC\Model;
class ModelsAuth extends Model {
...
}
I'm not fond of either of these options however, because then you've got a base class named \MVC\Model and a namespace named \MVC\Model, which is somewhat confusing. I'd recommend putting your base class as an abstract into the \MVC\Model namespace, in a file named MVC/Model/AbstractModel.php like this:
namespace MVC\Model;
abstract class AbstractModel {
...
}
And then your model in a file name MVC/Model/MyModel.php like this:
namespace MVC\Model;
class MyModel extends AbstractModel {
...
}
This way, all your models are in the same namespace and the same directory.
Also, if you use a PSR-4 autoloader then most of these sorts of issues will go away.

Class 'App\Http\Controllers\Illuminate\Container\Container' not found

I want to parse an XML.
I writed this ResultController
<?php
namespace App\Http\Controllers;
use Auth;
use \App\User;
use Illuminate\Http\Request;
use XmlParser;
use Illuminate\Container\Container;
use Orchestra\Parser\Xml\Document;
use Orchestra\Parser\Xml\Reader;
class ResultController extends Controller
{
public function getResults()
{
$xml = XmlParser::load('http://www.xmlsoccer.com/FootballDataDemo.asmx/GetAllTeams?ApiKey=ZXRIQOWMCFARAWRQIMSLRXCTSZDOBNLOTYWXYXMZYGDSENFSRB');
$app = new Illuminate\Container\Container;
$document = new Orchestra\Parser\Xml\Document($app);
$reader = new Orchestra\Parser\Xml\Reader($document);
$xml = $reader->load('http://www.xmlsoccer.com/FootballDataDemo.asmx/GetAllTeams?ApiKey=ZXRIQOWMCFARAWRQIMSLRXCTSZDOBNLOTYWXYXMZYGDSENFSRB');
$user = $xml->parse([
'users' => ['uses' => 'Team[Team_Id,Name]'],
]);
// dd($xml);
return view ('results.live');
}
}
I used use Illuminate\Container\Container; at top of the controller but it gaves me this error:
FatalErrorException in ResultController.php line 13: Class
'Illuminate\Container\Container\Controller' not found.
I cant understand what is wrong with it?
If you've used use keyword above -
use Illuminate\Container\Container;
use Orchestra\Parser\Xml\Document as OrchestraDocument;
use Orchestra\Parser\Xml\Reader as OrchestraReader;
you should use it inside method as (updated):
$app = new Container;
$document = new OrchestraDocument($app);
$reader = new OrchestraReader($document);
As you've used new Illuminate\Container\Container the php would find
your container as -
App\Http\Controllers\Illuminate\Container\Container, which isn't the
correct path, the use keyword helps php to recognize the namespace
of class Container
For more info see PHP Namespacing Docs
Hope this helps!

PhalconPHP - Unable to load a component from the DI in a controller

I am trying to create an ACL component as a service, for a multi-module PhalconPHP application. When I call the ACL component from the Controller Base, I am getting an error that I can't re-declare the ACL class.
Any ideas how to fix it, and understand the logic of why it is re-initialized again?
Fatal error: Cannot declare class X\Acl\Acl because the name is already in use in C:\xampp\htdocs\x\app\common\Acl\Acl.php on line 12
Update:
If I changed everything to "Pacl" then it works. I assume there might be a mixup with the PhalconPHP namespace. I am either not using the namespaces properly, or there's a bug in PhalconPHP 2.1 Beta 2.
/app/common/Acl/Acl.php
namespace X\Acl;
use Phalcon\Mvc\User\Component;
use Phalcon\Acl;
use Phalcon\Acl\Role as AclRole;
use Phalcon\Acl\Resource as AclResource;
/*
* ACL component
*/
class Acl extends Component {
private function initialize() {
}
public function isAllowed() {
die('called');
}
}
/app/front/controllers/ControllerBase.php
namespace X\Front\Controllers;
use Phalcon\Session as Session;
use Phalcon\Mvc\Controller;
use Phalcon\Mvc\Dispatcher;
class ControllerBase extends Controller {
public function beforeExecuteRoute(Dispatcher $dispatcher) {
//$this->acl = $this->getDI()->get("acl");
var_dump($this->acl->isAllowed()); //same behavior in both case
}
}
/app/front/Module.php
namespace X\Front;
use Phalcon\DiInterface;
use Phalcon\Mvc\Dispatcher;
use X\Acl\Acl as Acl;
class Module {
public function registerAutoloaders() {
$loader = new \Phalcon\Loader();
$loader->registerNamespaces(array(
'X\Front\Controllers' => __DIR__ . '/controllers/',
'X\Front' => __DIR__,
'X' => __DIR__ . '/../common/'
));
$loader->register();
}
public function registerServices(DiInterface $di) {
$di['acl'] = function() {
return new Acl();
};
}
}
This is not Phalcon issue. Look closely at your code:
namespace X\Acl;
use Phalcon\Acl;
class Acl extends ... {
}
What Acl interpreter should use? X\Acl\Acl or Phalcon\Acl?
The same error you get for example for the following code
namespace My\Awesome\Ns;
use Some\Name; # Name 1
class Name # Name 2
{
}

ZF2/PHP Namespacing - Which is quicker/better?

I've created my code as ZF2 pushes you to do it and now I'm starting to think that it's actually against the whole point/benefit of using namespacing in the first place.
I want to change everything but I'm scared to do it my way just because ZF didn't do it this way themselves so I feel like I have to be missing one important thing.
My folder/file structure is something like this:
- Application
- Controller
IndexController.php
- Model
- Table
User.php
Building.php
- Mapper
User.php
Building.php
- Entity
User.php
Building.php
So inside my controller, the code might look something like this, as ZF2 suggests you start out:
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController,
Zend\View\Model\ViewModel;
use Application\Model\Entity\User as UserEntity,
Application\Model\Mapper\User as UserMapper,
Application\Model\Table\User as UserTable;
class IndexController extends AbstractActionController {
public function indexAction() {
$userEntity = new UserEntity;
$userMapper = new UserMapper;
$userTable = new UserTable;
Right there I've only given a few items but as your application grows, you end up with a HUGE use statement and it seems like it should be done more like the following:
namespace Application;
use Zend\Mvc\Controller\AbstractActionController,
Zend\View\Model\ViewModel;
use Model;
class IndexController extends AbstractActionController {
public function indexAction() {
$userEntity = new Entity\User;
$userMapper = new Mapper\User;
$userTable = new Table\User;
I'm guessing it's because ZF2 are pushing Modular based projects that have lots of modules. But surely then I could just throw in that module's namespace if required? I would still need to do that with the more qualified names as currently in use.
The use statement is to import a namespace and about how & when you import, there is no coding standard.
There are two things you have to keep in mind:
Yes, the use of many classes (or namespaces) might get too complicated. Therefore I usually import a namespace, without having the classes imported explicitly. Examples are here (for module features), here (for autoloading) and here (for exceptions). As you see, it's a mixture of FQCN and namespaces.
If you are scared for "if your application grows": think about classes as they encapsulate responsibility. If your class has more than one responsibility, split it into two classes. Then you will also notice your number of imported namespaces will decrease.
By the way, there is a use PSR-2 guideline that states use statements must end with ; for every single use. So not this:
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController,
Zend\View\Model\ViewModel;
use Application\Model\Entity\User as UserEntity,
Application\Model\Mapper\User as UserMapper,
Application\Model\Table\User as UserTable;
class IndexController extends AbstractActionController {
public function indexAction() {
$userEntity = new UserEntity;
$userMapper = new UserMapper;
$userTable = new UserTable;
}
}
But this:
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Application\Model\Entity\User as UserEntity;
use Application\Model\Mapper\User as UserMapper;
use Application\Model\Table\User as UserTable;
class IndexController extends AbstractActionController {
public function indexAction() {
$userEntity = new UserEntity;
$userMapper = new UserMapper;
$userTable = new UserTable;
}
}
So you might clean things up to this:
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Application\Model;
class IndexController extends AbstractActionController {
public function indexAction() {
$userEntity = new Model\Entity\User;
$userMapper = new Model\Mapper\User;
$userTable = new Model\Table\User;
}
}
And if you want to use your own entity and mapper, but a table from a different module, the code will get refactored into this:
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Application\Model;
use OtherModule\Model\Table\User as UserTable;
class IndexController extends AbstractActionController {
public function indexAction() {
$userEntity = new Model\Entity\User;
$userMapper = new Model\Mapper\User;
$userTable = new UserTable;
}
}

symfony2 routing issues

I am getting the following error:
The autoloader expected class "Acme\HelloBundle\Controller\HelloController" to be defined in file "/var/www/Symfony/app/../src/Acme/HelloBundle/Controller/HelloController.php". The file was found but the class was not in it, the class name or namespace probably has a typo.
The controller code I have is actually:
namespace Acme\HelloBundle\Controller;
use Symfony\Component\HttpFoundation\Response;
class HelloController
{
public function indexAction($name)
{
return new Response('<html><body>Hello '.$name.'!</body></html>');
}
}
any idea why this is?
<?php namespace Acme\HelloBundle\Controller;
....
Just add the "*LESS_THAN*"?php tag at the beginning. Try if works.
Your controller should extend Symfony\Bundle\FrameworkBundle\Controller\Controller
namespace Acme\HelloBundle\Controller;
use Symfony\Component\HttpFoundation\Response;
use namespace Acme\HelloBundle\Controller;
class HelloController extends Controller
{
public function indexAction($name)
{
return new Response('<html><body>Hello '.$name.'!</body></html>');
}
}

Categories