If I have a PHP namespace as follows:
<?php
namespace A\B;
$test = new MyClass();
it seems every time I create a new instance of class, the name is prefixed with the namespace, e.g.
$test = new A\B\MyClass();
What happens if I don't want to use a namespace for another class, e.g. I want to call
$test = C\D\AnotherClass();
Currently this becomes:
$test = A\B\C\D\AnotherClass();
which results in an error.
For php7 you can wrap code in a namespace then call it with use in the global namespace declared using namespace with no name per the example below.
namespace FRED\WILMA\BAMBAM {
const FW = 2;
function fw() {
echo "<br>fw<br>";
}
}
namespace BARNEY\BETTY { // Create Namespace and add function
function bb() {
echo "<br>bb<br>";
}
}
namespace { // use global namespace
use FRED\WILMA\BAMBAM;
use BARNEY\BETTY;
BETTY\bb();
BAMBAM\fw();
}
Related
In my script, I have two classes with the name "Exception".
Normally, I would use
use PHPMailer\PHPMailer\Exception;
and then, use the class Exception that points to PHPMailer.
The problem is that I can't use the "use" command inside a function. So how can I declare what exception to use each time?
Example:
use PHPMailer\PHPMailer\PHPMailer;
use PHPMAiler\PHPMailer\Exceptions;
use PHPMailer\PHPMailer\SMTP;
class email {
function send_with_smtp {
$a = new PHPMailer(); // inside this class it needs the exceptions to be used as a PHPMailer\Exceptions
}
function send_with_critsend{
$a = new MXM(); // inside this class it needs the exceptions to be used NOT as a PHPMailer\Exceptions
}
}
What I would do -but can't because use is used only in the upper level- is the following (that is wrong of course). But this is what I would like to achieve:
class email {
function send_with_smtp {
use PHPMailer\PHPMailer\PHPMailer;
use PHPMAiler\PHPMailer\Exceptions;
use PHPMailer\PHPMailer\SMTP;
$a = new PHPMailer(); // inside this class it needs the exceptions to be used as a PHPMailer\Exceptions
}
function send_with_critsend{
use ANOTHER; // maybe the default Exceptions or something else.
$a = new MXM(); // inside this class it needs the exceptions to be used NOT as a PHPMailer\Exceptions
}
}
Wouldn't you just reference the desired exception by its full name?
class alpha {
function alphafunction {
$a = new \PHPMailer\Exception\Exception();
}
}
class beta {
function betafunction {
$a = new \AnotherClass\Exception\Exception();
}
}
On one side you can use different files for different classes that use different Exceptions.
alpha .php
use PHPMailer\PHPMailer\Exception;
class alpha {
function alphafunction {
throw new Exception();
}
}
beta.php
use AnotherClass\Exception\Exception;
class beta{
function alphafunction {
throw new Exception();
}
}
But you can also do in one file:
use PHPMailer\PHPMailer\Exception as PHPMailerException ;
use AnotherClass\Exception\Exception as AnotherClassException;
class alpha {
function alphafunction {
throw new PHPMailerException();
}
}
class beta {
function betafunction {
throw new AnotherClassException();
}
}
Topic here: namespace aliases
If you want to know what exception you get from elsewhere do:
try {
//do stuff here
} catch(\Exception $e){
print get_class($e);
}
To use a namespace alias (also called a "using directive") inside a class or function, you can place the using keyword followed by the namespace and the alias you want to use at the top of your class or function definition. For example:
namespace MyNamespace
{
class MyClass
{
// Use the alias "alias" for the namespace "MyNamespace::MyOtherNamespace"
using alias = MyNamespace::MyOtherNamespace;
void MyFunction()
{
// Use the alias to access a class or function in the namespace
alias::MyClass instance;
instance.DoSomething();
}
}
}
In this example, the using directive creates an alias for the MyOtherNamespace namespace inside the MyNamespace namespace. This allows you to use the alias to access classes or functions in the MyOtherNamespace namespace without having to fully qualify their names.
I used to have several library classes with the exact same methods. Figured I'd learn a bit more about two important aspects of coding; Traits and DRY.
I have the following trait:
<?php
namespace App\Berry;
trait Lib
{
public function getIDs()
{
$oClass = new \ReflectionClass(get_called_class());
$aConstants = $oClass->getConstants();
foreach($aConstants as $sKey => $mValue)
{
if(!is_int($mValue))
{
unset($aConstants[$sKey]);
}
}
return array_values($aConstants);
}
}
The following class:
namespace App\Berry;
use Lib;
class postType
{
const POST_TYPE_BLOG_ID = 1;
const POST_TYPE_BLOG_LABEL = __('blog', 'lib');
const POST_TYPE_PAGE_ID = 2;
const POST_TYPE_PAGE_LABEL = __('page', 'lib');
const POST_TYPE_NEWS_ID = 3;
const POST_TYPE_NEWS_LABEL = __('news', 'lib');
}
And am calling it like this in my PicturesController class:
$cPostTypesLibrary = new postType();
$this->set('aPostTypes', $cPostTypesLibrary->getIDs());
Now to me, this seems almost exactly like the tell me to do in the docs example #4 (About using multiple traits)
The only difference I have is I have the use outside of my class due to getting cannot use class because it is not a trait
What am I missing here?
Your class is not using the trait, you are instead using the other use of the use keyword and trying to import the Lib class from the same namespace into, well, the same namespace.
To use traits correctly, go back to the documentation, and look at where they are placed. The use statement is placed inside of the class definition. In your case, it would look like this:
namespace App\Berry;
class postType
{
use Lib;
// ...
}
You have to declare the trait inside the class
class postType
{
use Lib;
}
I'm trying to run this code on the same file:
namespace Foo1\Bar\SubBar;
class SubBarClass {
public function __construct() {
echo 'From Foo1';
}
}
namespace Foo2\Bar\SubBar;
class SubBarClass {
public function __construct() {
echo 'From Foo2';
}
}
use Foo1\Bar\SubBar;
$foo1 = new SubBarClass;
use Foo2\Bar\SubBar;
$foo2 = new SubBarClass;
The ideia is to change namespaces and echo the related value.
But it's returning the following error:
( ! ) Fatal error: Cannot use Foo2\Bar\SubBar as SubBar because the name is already in use in C:\wamp\www\xxx\namespaces.php on line 30
Line 30: use Foo2\Bar\SubBar;
How can I interchange namespaces on the same file?
Thks!
use keyword is used to import that namespace to be accessed in your current file scope. It does not act as a namespace "instance constructor".
You're current under Foo2\Bar\SubBar namespace. Like a directory of classes, while you're here, you should access other namespaces from the root (\):
$foo2 = new SubBarClass;
$foo1 = new \Foo1\Bar\SubBar\SubBarClass;
There is no need to use use for those namespaces (although you can, specially when they share parent namespaces), they are already declared in the same file you're using them.
For more information about this, consider reading the manual, where it describes using multiple namespaces in the same file.
This happens because the last defined namespace is the one currently active.
So, when I type:
use Foo1\Bar\SubBar;
I'm still on the last defined namespace: Foo2\Bar\SubBar.
Hence, when I type:
use Foo2\Bar\SubBar;
I'm trying to use the currently active namespace. That's why the Fatal error is returned.
On possible solution is:
namespace Foo1\Bar\SubBar;
class SubBarClass {
public function __construct() {
echo 'From Foo1';
}
}
namespace Foo2\Bar\SubBar;
class SubBarClass {
public function __construct() {
echo 'From Foo2';
}
}
use Foo1\Bar\SubBar;
$foo1 = new SubBar\SubBarClass;
echo '<br>';
$foo2 = new SubBarClass;
Cheers!
I created a common.php for my all the global function. When I run my first function {{Common::test()}}
It's working fine But I can not use model in it.
namespace App\library;
{
class Common {
public static function test()
{
echo "Yes";
return "This comes from Common File";
}
public static function getCmsBlocks()
{
$model = Modelname::all();
if($model){
echo "asdad";
}else
{
echo "sadasd";
}
}
}
}
I don't get my output when I run {{Common::getCmsBlocks()}}
If your model is in different namespace than App\library you will need to prefix the model class name with its namespace, otherwise PHP will try to load App\library\Modelname which might not be what you need.
Replace
$model = Modelname::all();
with
$model = \Your\Model\Namespace\Modelname::all();
If you use your Modelname class in multiple place in declared namespace, you can import/alias that using use statement so that you can refer to that class by classname in your code:
namespace App\library;
use Your\Model\Namespace\Modelname;
{
class Common {
public static function getCmsBlocks()
{
$model = Modelname::all(); //this will work now
}
}
}
There is no way to define global use to bused by all namespaces in your file, as use always refers to the namespace being declared.
As above the answer is perfect but just a few addition if you don't want to include namespace everytime on at start of each file
Use this :
\App\ModelName::all();
\App\ModelName1::update(item);
\App\ModelName2::find(1);
give path like above and there will be no need to use namespace everytime .
Note: above is path to model which is inside App directory . So change accordingly if you are keeping them at separate place .
I have a file that require()'s a namespace, as such:
<?php
require_once('Beer.php'); // This file contains the Beer namespace
$foo = new Beer\Carlsburg();
?>
I would like to put the Beer namespace directly in the same file, like this (unworking) example:
<?php
namespace Beer {
class Carlsburg {}
}
$foo = new Beer\Carlsburg();
?>
However, the PHP interpreter complains that No code may exist outside of namespace. I can therefore wrap $foo declaration in a namespace, but then I must also wrap Beer in that namespace to access it! Here is a working example of what I am trying to avoid:
<?php
namespace Main\Beer {
class Carlsburg {}
}
namespace Main {
$foo = new Beer\Carlsburg();
}
?>
Is there any way to include the code for the Beer namespace in the file, yet not wrap the $foo declaration in its own namespace (leave it in the global namespace)?
Thanks.
You should use the global namespace :
<?php
namespace Beer {
class Carlsburg {}
}
namespace { // global code
$foo = new Beer\Carlsburg();
}
?>
See here -> http://php.net/manual/en/language.namespaces.definitionmultiple.php
Try this
namespace Beer {
class Carlsburg {}
}
//global scope
namespace {
$foo = new Beer\Carlsburg();
}
As per example #3 in Defining multiple namespaces in the same file
Try placing a backslash before the namespace name:
$beer = new \Beer\Carlsberg();
The initial backslash is translated to "global namespace". If you do not put the leading backslash, the class name is translated to the current namespace.
Just write it, it has no "name":
<?php
namespace Main\Beer {
class Carlsburg {}
}
namespace {
use Main\Beer;
$foo = new Beer\Carlsburg();
}
?>
Demo and see Defining multiple namespaces in the same fileDocs.