I'm making now things with php + Symfony2 framework, and I have the following code:
require_once("one_file.php");
require_once("another_file.php");
... and so on.
The problem is, how to "Symfonyze" these uncomfortable require sentences, and after, how to include these files in the Symfony2 package?
We've thought about two possibilities:
Include the file at /vendors directory of symfony, or
Include each class as a service.
If these classes reside inside bundle then you could use as below:
Suppose your bundle name is AcmeDemoBundle. Place this file inside Acme/DemoBundle/Model/
//one_file.php
namespace Acme/DemoBundle/Model;
class one_file {
...........
}
To use this file inside your controller or any other file:
Here for Acme/DemoBundle/Controller/UserController.php
namespace Acme/DemoBundle/Controller
use Acme/DemoBundle/Model/one_file
class UserController {
public $one_file=new one_file();
}
In php 5.3 onwards, namespaces has been introduced. You should probably look at namespaces and its uses in php documentation
You can follow the PSR-0 standard to let the autoloader handle this. See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md and http://getcomposer.org/doc/04-schema.md#psr-0 .
Or you could keep your files as is, and tell composer to require them each time : http://getcomposer.org/doc/04-schema.md#files
You have to make a folder in your acme folder like lib puts these files in lib folder then use this statement
use Acme\DemoBundle\lib\Abc; // its your class name
You want to follow these other answers, especially the approved one, but if you are using a third party library with tons of PHP files, you can do require_once(__DIR__.'/path/to/file.php') as a quick fix.
Related
This is my project path configuration
./create.php
/Install/Install.php
create.php
<?php
use Install\Install;
echo "Starting";
$install = new Install();
This gives me the error
PHP Fatal error: Uncaught Error: Class 'Install\Install' not found in /project/create.php:6
Install.php
<?php
namespace Install;
class Install
{
//whatever
}
Can someone explain me what is happening there ?
Obviously I guess that using a require_once line with my filename would probably fix the issue...but I thought using namespace and use import could prevent me from doing that like we do in classic framework like symfony / magento ?
I've seen some post speaking about autoloading, but i'm a little bit lost. Haven't been able to find a clear explanation on the other stack topic neither.
PHP compiles code one file at a time. It doesn't have any native concept of a "project" or a "full program".
There are three concepts involved here, which complement rather than replacing each other:
Namespaces are just a way of naming things. They allow you to have two classes called Install and still tell the difference between them. The use statement just tells the compiler (within one file) which of those classes you want when you write Install. The PHP manual has a chapter on namespaces which goes into more detail on all of this.
Require and include are the only mechanisms that allow code in one file to reference code in another. At some point, you need to tell the compiler to load "Install.php".
Autoloading is a way for PHP to ask your code which file it should load, when you mention a class it hasn't seen the definition for yet. The first time a class name is encountered, any function registered with spl_autoload_register will be called with that class name, and then has a chance to run include/require to load the definition. There is a fairly brief overview of autoloading in the PHP manual.
So, in your example:
use Install\Install; just means "when I write Install, I really mean Install\Install"
new Install() is translated by the compiler to new Install\Install()
the class Install\Install hasn't been defined; if an autoload function has been registered, it will be called, with the string "Install\Install" as input
that autoload function can then look at that class name, and run require_once __DIR__ . '/some/path/Install.php';
You can write the autoload function yourself, or you can use an "off-the-shelf" implementation where you just have to configure the directory where your classes are, and then follow a convention for how to name them.
If you want to Use class from another file, you must include or require the file.
Use require('Install.php'); before use Install\Install;.
If you are planning to do a big project I would recommend to use PHP frameworks rather than coding from scratch.
Inside my Controller I want a function to use mpdf e.g.
public function actionPdf(){
include("MPDF57/mpdf.php");
$mpdf=new mPDF('c');
$mpdf->SetDisplayMode('fullpage');
$mpdf->WriteHTML("<h1>Hello World!</h1>");
$mpdf->Output('filename.pdf', 'F');
}
}
This does not work, and throws an error:
Class 'app\controllers\mPDF' not found
What should I do If I want to autoload the class
(a). Just for this Controller Action
(b). To make it usable everywhere just by using the use statement.
I know it has to do something with namespaces but don't know how do I define a namespace, and where do I place this MPDF57 folder and then make it accessible.
I also tried this :
$name = "MPDF57/mpdf.php";
spl_autoload_register(function ($name) {
var_dump($name);
});
But this didn't work either. throws the same error when I call my controller Action.
Here is the namespace declaration and use statements inside :
namespace app\controllers;
use Yii;
use app\models\Regs;
use app\models\Voters;
use app\models\RegsSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use \yii\web\Response;
use yii\helpers\Html;
use kartik\mpdf\Pdf;
Yii has already had autoloader, you do need nothing to load your class.
Just create your class with correct namespace and it will be loaded where are you using it only.
Namspace should represent real path to PHP file. PHP file name and class name should be same.
You should simply use mpdf/mpdf package :
Install it using composer :
composer require "mpdf/mpdf" ">=6.0.0"
Use it like this :
$mpdf = new \mPDF();
Or you can use a yii2 extension like this one : https://github.com/kartik-v/yii2-mpdf
I've faced such problems in one of my previous projects. I'm not good at PHP or Yii2 - so follow my guide on your own risk :)
When you you add use path\to\ExternalLibrary that means the interface is ready to use inside current class (e.g. CurrentController.php).
That means your application knows how to bring your path to it's stage.
E.g. use common\models\Post lets you directly to use Post class, as $posts = new Post;
So if your library contains only one file, just put is some "canonic" path. To common\models\ for example. So you can use it like any other model interface.
But for sake of your project put it on vendor folder. Then install a random library with composer. And observe which files are modified (1-3 generally). Also try to understand the modification logic. When you get sure that you've grasped everything, copy and paste these parts and change the paths, names, etc. for your library.
The best way, I think, is to make your library PSR-4 compatible and ship it as a PHP package. Thus, others can also benefit from your work.
There are lots of guides about making php packages.
http://sitepoint.com/starting-new-php-package-right-way/
https://knpuniversity.com/screencast/question-answer-day/create-composer-package
http://jessesnet.com/development-notes/2015/create-php-composer-package/
http://culttt.com/2014/03/12/build-php-package/
If you are planning to be a good PHP developer, I recommend to look up Josh Lockhart's "Modern PHP: New Features and Good Practices" book ( free pdfs are available :) ). That will help you to understand the fundamentals of OO PHP including namespaces, interfaces etc. So, you will be able to handle such problems in modern way.
trying to work something out. I have my root folder which has index.php. Inside this folder is another folder called classes. Inside classes, I have three classes which have the namespace classes e.g.
<?php
namespace classes;
class MyClass {
...
Now back to index.php, this is not a class. However, I need to use these classes in the classes folder. I am trying without success
<?php
$reader = new \classes\MyClass();
With this I get the error that the class is not found. I have also tried using a require, but because MyClass requires the use of another class in the folder, it means I have to require both classes to get it working. So my only solution at the moment is
<?php
require_once('classes/MyClass.php');
require_once('classes/MySecondClass.php');
$reader = new \classes\MyClass();
For some reason I do not think this is the correct way to do it. What is the appropriate way to use my classes in index.php?
Thanks
When you try to work with namespaces you could use the PSR-4 convention and you could use the composer autoloader. Its very simple and you have a good structure.
http://jessesnet.com/development-notes/2014/php-composer-autoloading/
Here is a good article that describes how to use the PSR-4 autoloader. It's the new way in working with Files and dependencies. And you have the ability to work with all other packages that use composer, too.
Use autoloader see here
and here
I want to add an external lib into my symfony 2 project. I use the 2.4 version. I have read many "how to" but all solution doesn't work with this version.
Do you tell me how I can do to add my class in my project ?
My class Html2Pdf:
<?php
class Html2Pdf
{
// Code ...
}
?>
Do you know anything about services?
If you want to use that YoutubeDownloader class in controllers, you have to define it as a service so you can call anywhere you want.
Open your services.yml in;
YourBundle/Resources/config/services.yml
parameters:
youtubeDownload: YourBundle/YourPathToClass
services:
bundlename.controllername.controller:
class: "%youtubeDownload%"
More information:
http://symfony.com/doc/current/cookbook/controller/service.html
You can call it in a class using \Html2Pdf as you can with any none namespaced class.
Update:
As you are using Symfony and Composer the classes and namespace will already mapped so you simply need to include it using the \Html2Pdf namespace. The \ is to signify that it is a namespace based at the root level rather than a relative namespace (in the same folder).
If you were not using composer or something with an autoloader then you would need to include the file somewhere in your stack (this can be in the current file or some kind of parent file that serves this one) using include_once('**path to file**/Html2Pdf.php'). You would then use it in the same way as you would when using Symfony/Composer with the \.
This works for me.
include_once $this->get('kernel')->getRootDir() . '/../path/to/Html2Pdt.php';
$aHtml2Pdt = new \Html2Pdt();
I think this is what #Qoop is trying to say to.
I hope it helps.
I have a site which uses the library file lib.client.php which is stored in the php folder in my standard website root and contains a series of classes I have built.
The library file contains about 5 or so classes, should I leave this file as one or break up the classes into their own files and include them all individually? Are there any best practice naming conventions I should use for these file(s)?
(As you can see at the moment I'm using lib. and I also use inc. - only because I have seen it done a few times before).
UPDATE:
I am remodelling my structure to comply with the PSR-0 Standard. I now have:
CCall (Vendor)
Core
Connection
Gateway.php
GatewayDSN.php
GatewayException.php
Components
Environment.php
EnvironmentRequest.php
Centre.php
Access
User.php
UserSession.php
RenderException.php
I want to create a new Environment() in index.php, and its __construct method calls Gateway::checkInstance().
How would I manage namespace use in this model? What would have its own namespace and where would I define this?
How would I use an autoload with these namespace definitions (and where?)
Is there an equivalent standard for method and property naming?
I am using this https://gist.github.com/jwage/221634/download#
Break classes into their own files and follow the PSR-0 standard as a best practice.
http://phpmaster.com/autoloading-and-the-psr-0-standard/
If you are using a PSR-0 autoload:
add this in Environment.php
namespace Components;
and add a reference to Gateway
use Core\Connection\Gateway;
of course you need this line inside Gateway.php
namespace Core\Connection;
Then:
new Components\Environment();