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
Related
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.
I'm currently reading Modern PHP Book and I'm a little confused since in Chapter 2 the author talks about Namespace and he keeps saying import when he refers to the "use". In fact he states the following...
TIP
You should import code with the use keyword at the top
of each PHP file, immediately after the opening <?php tag or...
The way I understand Namespace is that the use keyword references the namespace of the class but it doesn't import it and you still need to use require or include to import the actual class, correct?
I'm I correct when I say that when using namespace without auto-loading you will need to use require or include to import your classes?
Thanks
If you use autoloader, such as composer, you do not need to import or require PHP files (you only load autoloader file, which actually does all that for you). If you have no autoloader, you have to load files using import or require.
Then, after FILE is loaded, you can use use statements to do actual work with name-spaced items, such as classes, interfaces or traits.
Yes, you're correct. The use keyword in PHP merely aliases a namespace, in that it does what a symlink (on a *nix system) or shortcut (on a Windows system) would.
If you read the manual about PHP namespace basics you'll see that namespaces can be analogous to a filesystem where class/interface/constant/function names can be divided up into folders in order to prevent name-clashes.
If you read the manual section on Namespace Importing you'll see that when we refer to importing in PHP it actually means to create a shortcut of one name to another name (in fact the shortcut analogy above is taken right from the manual)...
This is similar to the ability of unix-based filesystems to create symbolic links to a file or to a directory.
So, while confusing, the use keyword in PHP does not attempt to load (or include) the actual file containing the namespace, but rather just creates an alias for given namespace(s).
This may be very different use of the word import than you may be used to in other languages, where import can mean to load the actual file or package, but in PHP it's important to understand that importing a namespace has nothing to do with autoloading or including files. They are two separate concepts in PHP.
Importing a namespace is so that you can refer to \fully\qualified\namespace\MyClass as simply MyClass inside your namespace rather than having to use the FQN every single time (hence the shortcut analogy).
Autoloading, is for including the actual classes in PHP when they get used in code.
So there's a definite disconnect between the two concepts.
Since you mentioned a Chapter 2 in a book, I'm going to assume that you are still learning PHP, yes?
The use of use is to shorten namespaced classes to their root so that if you have some long namespaced class like
org\shared\axel\web\framework\connection\pipeline\impl\StopExecutionException
that needs to be instantiated with
new org\shared\axel\web\framework\connection\pipeline\impl\StopExecutionException();
You can use use to refer only to the root unnamespaced class
use org\shared\axel\web\framework\connection\pipeline\impl\StopExecutionException;
...
throw new StopExecutionException();
Keep in mind that you still need to have the class's code in your script, so you either include/require that manually by using include or require, or register autoloaders (see spl_autoload_register).
What that does is you define how your namespace maps to your source code's directory structure.
What others here refer to as composer is a package manager that includes an autoloader. At this stage, I personally think it's better to put off learning about this until you have a good grasp of the basics.
If you have an autoloader then use can be used to pull a Trait
Trait file
namespace Blah;
Trait Foo {
protected $somevar;
}
Class file
Class Bar {
use \Blah\Foo; // autoloaded
}
Otherwise, use is used to indicate that you want to either load a given class or alias that class as another
Class Foo {
}
use \Foo as Bar;
Class Something extends Bar {
}
I'm a beginner to L5. I read the documentation about extending classes but i didn't find any information about where to put the file in which i extend the class.
**I have to extend Str.php class. I have read that in L4 it had to be done by putting that file under App/folder but i didn't find that folder in L5.
So please can you tell me how can i do that?
This is the information i have now:
First, you must find where the class file is. We will be extending the Str class, which is under vendor/laravel/framework/src/Illuminate/Support. Note that you can also find this class under the aliases key in app/config/ app.php.
Now create a new folder called lib under app/folder. This folder will hold our class extensions. Because the Str class is grouped under the folder Support, it is suggested that you create a new folder named Support under lib too.
Now create a new file named Str.php under app/lib/Support, which you've just created:
But this is for L4
That's more of a general PHP question and there are two parts: 1) How to extend a class and 2) where to put files.
1) Extending classes isn't something Laravel or anyone else provides. That's right there in the language:
class A {}
class B extends A {}
As long as class A exists and is available, then class B can extend from it.
2) Where the files are is also important here. If you're defining class B and want to extend class A, the php runtime needs to know where to find A. Usually class A isn't defined in the same file as class B.
There are many ways to do this. You could require or include class A when you define class B. That would look something like:
a.php
class A {}
b.php
require "a.php";
class B extends A {}
Now with a lot of files like in the Laravel framework or any worthy library, you're going to have a lot of files to include and have to keep track of how to include those files. That's no fun. So, instead of doing that, PHP has provided a way to autoload the classes. That is, if you define classes in a predictable way, PHP can figure out what classes you're talking about without you having to use require or include statements.
There are also many ways of autoloading php files. In Laravel (and many, many other projects), the composer autoloader is used.
This means that files have to be placed in a pre-defined way in order for the composer autoloader to find them. By reading about the composer autoloader and then digging into the code to see how Laravel's classes are autoloaded, you'll be able to figure out how that happens.
Despite the intricate detail of Peter's answer, I figured I'd write something much more concrete: it doesn't matter.
If you check composer.json, you'll see that we are autoloading everything that is placed inside the app directory anyway. Hence, the choice is really yours. All that matters is that you maintain a sensible and readable structure. For example, you could place it in app/Lib, and namespace all your classes App\Lib (if App is your base namespace of course, which can be changed with php artisan app:name). Of course, you could also have a folder like Helpers/Lib for your extended classes, and keep some form of helpers.php with global helper functions in Helpers.
Why would you do this? Well, you might want to have an easy way to call your new Strfunctions, so instead of having to do Str::yourNewMethod($argument) everywhere, you could add a helper function yourMethod($argument) to easier call the function (if you intend to use it extensively).
One thing you have to remember though, as mentioned by Peter, is that the class you are extending won't automagically be found. It will, however, be autoloaded. Hence, to reference it you have to remember to namespace it, such as in the example below.
<?php namespace App\Helpers\Lib
Class Str extends \Illuminate\Support\Str {}
Also remember to namespace correctly when you call your own class.
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();
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.