Silex, loading own classes - php

I play around with Silex, PHP micro-framework. At the moment I try to load my own classes but I have no luck doing it. Maybe somebody could explain me a little how does loading in Silex works?
My project structure looks like this:
app/
vendor/
web/
tests/
bootstrap.php
composer.json
composer.lock
Let's say I want to load a class Controller\User (namespace here) from /app/MainController.php.
How can I do that? I've browsed some articles (loading via Composer or Symfony's UniversalClassLoader), followed some instructions, and still it does not work.
If someone could give me a hand with it please, I would appreciate it.

I assume you load your Silex classes in bootstrap.php like that:
// bootstrap.php
require_once __DIR__.'/vendor/autoload.php';
If so replace this code with the following:
// bootstrap.php
$loader = require __DIR__.'/vendor/autoload.php';
$loader->add(YOUR_NAMESPACE, DIRECTORY_OF_THE_NAMESPACE);
Example:
// bootstrap.php
$loader = require __DIR__.'/vendor/autoload.php';
$loader->add('Tutorial', __DIR__.'/src');
You can add multiple namespaces if you like, just call the add method for every namespace.
In src/ you would store your class files. For every namespace create a folder which contains your class files for this namespace.
The file should have the same name as the class.
MyNamespace\MyClass => src/MyNamespace/MyClass.php
MyNamespace\SubNamespace\SubClass => src/MyNamespace/SubNamespace/SubClass.php
In every class file you have to set the associated namespace in the first line.
// src/Tutorial/DemoController.php
namespace Tutorial;
class DemoController{
// class definition goes here..
}
You have now access to your classes in every file which includes bootstrap.php.
In /app/MainController.php you can now access your own class like this:
// app/MainController.php
use Tutorial\DemoController;
$foo = new DemoController();
This solution worked for me. Hope it works for you.

I was also looking for the same thing, since Silex documentation still has the registerNamespace function that was removed.
Found a really nice answer here
In Short, all you have to do, is add a "psr-0" in "autoload" section in the composer.json
Example composer.json:
{
"require": {
"silex/silex": "~1.3",
"doctrine/dbal": "~2.2"
},
"autoload": {
"psr-0": {
"MyApp": "src/"
}
}
}
Make sure to update the Composer Autoloader ("composer install" or "composer update")

As of October, 2014 the best way to autoload your own classes into silex, is using PSR-4 (instead of PSR-0) autoloading through Composer using composer.json file in your application root:
{
"require": {
"silex/silex": "~2.0",
},
"autoload": {
"psr-4": {"Vendor\\Namespace\\": "path/to/src/"}
}
}
After editing your composer.json you need to do a:
composer update
on your project root directory, using terminal.

Related

PHP: Autoloading via PSR-4 is saying class not found

I am trying to use a class in my src folder, DependencyContainer, but it is saying class not found?
Index:
<?php
$dc = new \Mango\DependencyContainer();
File structure:
src/
DependencyContainer.php
index.php
composer.json
composer.json:
{
"name": "mqwerty/ioc-container",
"type": "library",
"require": {},
"autoload": {
"psr-4": {
"Mango\\": "src/"
}
}
}
DependencyContainer class:
<?php
declare(strict_types = 1);
namespace Mango;
class DependencyContainer
{
}
First you need to add the autoload file in your index like this
require __DIR__ . '/vendor/autoload.php';
And your index.php is going to sth like this
<?php
require __DIR__ . '/vendor/autoload.php';
$dc = new \Mango\DependencyContainer();
It will solve your problem
Autoloading doesn't just happen automagically; composer is set up to manage the creation and updating of your PSR autoloading based off the PSR settings of your composer.json.
Do a composer install in your CLI; that will generate the autoload files in the vendor folder based off of your composer.json and create a composer.lock file, even if you don't have any dependencies.
From there, you will need to bootstrap the autoload file before executing your code.
Hey this has already been solved many times but ill still explain just incase you didnt understand others questions.
So I had this problem once too and you can find it on my profile.
psr works based on your path. when you set your src path thats where it starts from,
for example, your layout is something like the following:
vendor
your-vendor-name
your-package
src
App.php
Class.php
composer.json
then your psr location should have this after the : "/src"
and before it should be something like the following:
"your-vendor-name\your-package\"
when using a class, make sure you composer class names start with an uppercase letter and the class inside matches the file name, make sure the class namespaces are something like this \your-vendor-name\your-package
and to use
$app = new \your-vendor-name\your-package\(then the class name you want to use, so lets say, Class.php, then you would put Class() here)
hopefully this should solve your problem

Composer doesn't autoload packages

I'm currently developing a framework but I couldn't figure out how am I going to set autoloading. First I created a package with sample class and composer.json. I've autoloaded that sample class by:
"autoload": {
"classmap": [
"libs/"
]
}
I've checked /vendor/mypackage/vendor/composer/autoload_classmap.php and confirmed that package's autoloader is working fine. But the problem is I can't reach that package's class from main app unless I directly include that package's autoload.php.
UPDATE
/vendor/foo/mypackage/composer.json
"autoload": {
"psr-4": {
"Http\\": "libs/"
}
}
/vendor/foo/mypackage/libs/Request.php
namespace Http;
class Request {}
First of all, it's often better to use psr-0 or psr-4 autoloading config. With the classmap, you have to redump the autoloader each time you add a new class or rename one.
You always need to include the Composer autoloader by using require 'vendor/autoload.php';. The best place to add such require statement is in your front controller file.
Solved it by myself. I just had to reinstall package whenever I change pacakge's composer.json.

Using Composer Packages with Slim PHP 2.0

I am trying to build a REST API using Slim PHP 2.0, Composer, and a couple third-party packages. I used Composer to install Slim by creating a composer.json file in the root of my application with the following:
{
"require": {
"slim/slim": "2.*"
}
}
After I ran composer install I have the following structure:
root/
vendor/
composer/
slim/
autoload.php
composer.json
composer.lock
index.php
I want to include the Valitron (https://packagist.org/packages/vlucas/valitron) library to do validation along with this Bcrypt (https://packagist.org/packages/openlss/func-bcrypt) library to hash passwords for users. So, I made the following additions to my composer.json file so the it looks like this:
{
"require": {
"slim/slim": "2.*",
"vlucas/valitron": "dev-master",
"openlss/func-bcrypt": "dev-master"
}
}
After I ran composer update I got the following directory structure.
root/
vendor/
composer/
openlss/
slim/
vlucas/
autoload.php
composer.json
composer.lock
index.php
From here, I am not sure how to set up the autoloading for my application. I sometimes see autoload classmap and other times see psr-0. On top of these third-party packages I am going to be creating my own models to use. One will be a base model that handles connecting to the database and then each table will have a model that I use to manipulate the said table with. So for interacting with the users table I will use my UserModel.php file below. My other question is how would I go about "using" the Valitron and BCrypt files within this one? Would I just do this:
<?php namespace Libraries;
use \Valitron;
use \BCrypt;
class UserModel extends BaseModel {
// I want to use the Valitron class here along with the crypt file
}
How would I go about setting up autoloader to accomplish this? Any help is greatly appreciated. I already dislike Composer a lot but since everyone is saying it's a must for PHP developers I am trying to force myself to learn it.
Composer provides an autoloader for third-party libraries specified in composer.json. See https://getcomposer.org/doc/01-basic-usage.md#autoloading. You can customise the autoloader for your needs, it supports both PSR-4 and classmap. See the autoload reference for more details.
I mean, it's pretty simple in reality. If you want these classes to be autoloaded, then require autoload.php
require 'vendor/autoload.php';
Or, in composer.json you can declare it.
{
"autoload": {
"psr-0": {"Libraries": "vendor/open-lss"}
}
}
Which will allow you to do:
namespace Libraries\func-bcrypt
class bCrypt_class{
}
which is what I believe you are attempting to achieve

Custom code management with the Composer auto loader?

I've started a new project, where I use Composer to handle some dependencies, as well as their auto-loading.
I only keep the composer.json file in the VCS, instead of the entire vendor directory, so I don't want to start adding my code in there.
How should I handle my own project specific code, so that it auto loads as well?
This is actually very simple. Excluding vendors directory from your repository is the right approach. Your code should be stored in a separate place (like src).
Use the autoload property to make that composer recognizes your namespace(s):
{
"autoload": {
"psr-4": {
"Acme\\": "src/"
}
}
}
Assuming you have class names following the psr-4 standard, it should work. Below some example of class names and their locations on the file system:
Acme\Command\HelloCommand -> src/Command/HelloCommand.php
Acme\Form\Type\EmployeeType -> src/Form/Type/EmployeeType.php
Remember to define a namespace for each class. Here's an example of Acme\Command\HelloCommand:
<?php
namespace Acme\Command;
class HelloCommand
{
}
Don't forget to include the autoloader in your PHP controllers:
<?php
require 'vendor/autoload.php';
Read more on PSR-4 standard on PHP Framework Interoperability Group.
Note that if you edit composer.json, you need to either run install, update or dump-autoload to refresh the autoloader class paths.

add a library to silex

I know this question has already been asked, but it seems that autoloading process changed a little bit with composer.
I just want to add a class library to my silex project.
So I made this file:
vendor\lib\picture.php
<?php
namespace MyNamespace;
class Picture
{
function testage()
{
echo 'hihaaa ça marche'; exit;
}
}
in vendor/composer/autoload_namespaces.php, I added this line to the big array:
'MyNamespace' => $vendorDir . '/lib/',
And in the main file I added:
use MyNamespace\Picture as Picture;
and called it like that:
$app->register(new Picture());
which gives me this error:
Fatal error: Class 'MyNamespace\Picture' not found...
I just don't know how to add a class that I can use from any controller, easily, without command line (I don't use composer, I downloaded silex preconfigured), any idea?
If you're using composer you should not change the vendor directory. You should not add files into it, and you should not modify the composer-generated files.
I recommend you put those classes into the src directory. #gunnx shows how you can configure autoloading in composer.json, so that it gets re-generated every time you run composer install.
The file would be in src/MyNamespace/Picture.php. The autoload config in composer.json would be:
{
"autoload": {
"psr-0": { "MyNamespace": "src/" }
}
}
The actual solution is a combination of the two previous answers. But I think it's important to get the details right ;-).
Your Picture class should be in this file: vendor/lib/MyNamespace/Picture.php. Note the full namespace and the casing.
You can add your own code to the autoloader by adding the following to your composer.json
e.g.
{
"autoload": {
"psr-0": {"Acme": "src/"}
}

Categories