PHP namespace syntax - php

I am new to PHP and would appreciate some help with namespaces.
I have a class and it's declared as:
namespace P3;
class CardstreamCodingStandard_Sniffs_Classes_ClassDeclarationSniff {
}
Now i want to implement an interface called CodeSniffer_Sniff. So i amended the class declaration as:
namespace P3;
class CardstreamCodingStandard_Sniffs_Classes_ClassDeclarationSniff extends CodeSniffer_Sniff {
}
But when I run the code I get
Fatal error: Interface 'P3\CodeSniffer_Sniff' not found in /root/qa/CardstreamCodingStandard/Sniffs/Classes/ClassDeclarationSniff.php
Please can someone explain what is going on? and what the correct syntax should be?
Thanks
Ok some more details
I have inherited this code that implements a sniff for phpcs
My class is declared as
namespace CardstreamCodingStandard\Sniffs\Classes;
class CardstreamCodingStandard_Sniffs_Classes_ClassDeclarationSniff implements PHP_CodeSniffer_Sniff {
}
when I run phpcs with this sniff then I get the error
PHP Fatal error: Interface 'CardstreamCodingStandard\Sniffs\Classes\PHP_CodeSniffer_Sniff' not found in /root/qa/CardstreamCodingStandard/Sniffs/Classes/ClassDeclarationSniff.php on line 23
PHP Stack trace:
PHP 1. {main}() /usr/bin/phpcs:0
PHP 2. PHP_CodeSniffer_CLI->runphpcs() /usr/bin/phpcs:25
PHP 3. PHP_CodeSniffer_CLI->process() /usr/share/pear/PHP/CodeSniffer/CLI.php:113
PHP 4. PHP_CodeSniffer->initStandard() /usr/share/pear/PHP/CodeSniffer/CLI.php:956
PHP 5. PHP_CodeSniffer->registerSniffs() /usr/share/pear/PHP/CodeSniffer.php:594
PHP 6. include_once() /usr/share/pear/PHP/CodeSniffer.php:1409
I hope this makes things clearer

Some details on how to use namespaces can be found at the php manual.
In your case it seems you are using the same namespace.
To correctly use an interface, you have to implement it into your class.
The correct use would be the following:
Class Apple implements Fruit { ... }
More on interfaces and how to use them can be found here.
You are using the extends keyword which is used for creating child classes of a parent class.
The php manual on parent and child classes (called inheritance) has been linked here

you can follow this role :
file1:
<?php
namespace foo;
class Cat {
public function says(){
echo 'meoow';
}
}
?>
file2:
<?php
include 'file1.php';
use foo;
class bar extends foo{
//......
}
more details: http://php.net/manual/en/language.namespaces.php

You have to implement an interface, not extend. Try this:
class CardstreamCodingStandard_Sniffs_Classes_ClassDeclarationSniff implements CodeSniffer_Sniff {
}

Related

Why can't I instantiate this class?

Trying to build a simple oop solution but can't understand why I can't instantiate this class. I'm using an interface, class and implementing the class on an index.php but I'm getting a not found class error. What am I doing wrong?
Interface:
namespace interfaces;
interface ISales
{
}
Class:
namespace classes;
use interfaces\iSales;
class Sales implements iSales
{
}
Implementation (index.php):
use classes\Sales;
$sales = new Sales();
Error:
PHP Fatal error: Uncaught Error: Class 'classes\Sales' not found in ...
Error: Class 'classes\Sales' not found in
Thanks for all the comments. I've just used composer for that using this example: https://enterprise-level-php.com/2017/12/25/the-magic-behind-autoloading-php-files-using-composer.html
I'm coming from C# so PHP works a little bit different.

Can't find PHP class after implementing namespaces

I am dealing with an old PHP class called Config in a Config.class.php file.
Recently, I have implemented namespaces:
<?php
namespace Tfr\Partners\Smartfocus;
use Tfr\BaseApp;
class Config
{
...
} else {
$isProd = BaseApp::isProd();
}
...
When I am running the code, I now get the following error message:
Fatal error: Class 'Tfr\BaseApp' not found in
<some_path>/Partners/Smartfocus/Config.class.php on line 45
but the BaseClass is there in a file called <some_path>/BaseApp.class.php. However, it does not have a namespace itself.
Unfortunately, it is used in many places in a large code base, and adding a namespace to BaseClass seems very risky.
How can I 'import' BaseClass in Config safely and get rid of my error?

Are namespaces in PHP "inherited"?

EDIT:
Yes the problem was using \ at the beginning of the use statement. As M1ke pointed out, use goes from the root element.
Original post
I think is a PHP question but it may be Drupal.
I'm working on a headless Drupal project where is using a class (which I call Entity Model) that uses a Drupal class called EntityFieldQuery.
Before a create or use this class I bootstrap Drupal using:
require_once DRUPAL_ROOT.'/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
The entity model class is in the Models names space like so:
namespace Models;
use \EntityFieldQuery;
class EntityModel
{
.....
$query = new EntityFieldQuery();
$query->doSomething();
......
}
The EntityFieldQuery is found perfectly as I use the "\" because this class is out of the Models namespace.
The problem is when this class is created is uses other classes that don't use any namespace, and I have the following error:
class Models\InsertQuery not found in ....
Here is the class used by EntityFieldQuery that uses InsertQuery
class InsertQuery_mysql extends InsertQuery ...
I don't understand why InsertQuery_mysql is found but InsertQuery
I ended up adding a "\" in InsertQuery to fix the problem like so:
class InsertQuery_mysql extends \InsertQuery ...
Actually this class in a php file called query.inc that contains two defitinion classes (in the same file, I don't know this is a a problem too)
class InsertQuery_mysql extends InsertQuery
....
class TruncateQuery_mysql extends TruncateQuery
I thought that if I use "new \ClassName()" the "default namespace" inside this class would be "\" too and not the first called class's namespace.
I don't like to modify 3rd party libraries, is any way to avoid this? I guess is a architecture problem rather than a lack of definition if someone has a better idea, I appreciate.
Thanks!
EDIT2: Adding more info...
In order of execution.
index.php:
require_once 'vendor/autoload.php';
require_once DRUPAL_ROOT.'/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
...
app/SiteController.php:
use Models\Campaign;
class SiteController {
...
$campaing = new Campaign();
...
app/Models/Campaing.php:
namespace Models;
class Campaign extends EntityModel {
...
app/Models/EntityModel.php:
namespace Models;
use \EntityFieldQuery; //<-- this should go without \ as I say in EDIT section
class EntityModel {
...
public function getAll() {
$query = new EntityFieldQuery(); //<--throwed Models\InsertQuery not found. It must have \ at the beginning of the class name.
To answer the base question (and pending further code) PHP namespaces are set by whichever namespace is declared in the file.
// Bar.php
namespace Foo;
class Bar {}
// some other file
use Foo\Bar;
$test = new Bar(); //works
// different file
namespace Foo;
$test = new Bar(); // works
// another file
require 'Bar.php';
// won't work because we are not in namespace "Foo"
$test = new Bar();
In your specific case it the use \EntityLoader should be use EntityLoader because you're exiting the namespace you want to be inside.

PHP namespace confusion, class not found

I have two classes in the same folder in own files. But when I am trying to extends one to another it is giving namespace and class not found error.
Info: It is the first time I am extending class using namespace. Also nested namespace is new to me. DB\CRUD So may be I am doing
completely wrong with namespace.
Error message:
Fatal error: Class 'DB\AT_Database' not found in /var/www/...
DB class
File: AT_Database.php
namespace DB;
class AT_Database
{
...
}
CRUD class
File: AT_CRUD.php
namespace DB\CRUD;
use DB\AT_Database;
class AT_CRUD extends AT_Database
{
public function __construct()
{
}
}
This may be silly mistake or may be I have overlooked it (which I should not as a programmer) and that is loading sequence of the class.
May be it's not worth to have as an answer but just adding so by chance in future it can help to someone who make such mistake.
As I mentioned in one of my comment, I am using glob to auto load all class files to include.
foreach ( glob( $this->classes_dir . "/*.php" ) as $class ) {
include_once $class;
}
Now my file names are AT_CRUD.php and AT_Database.php. Here I realized that php loads files in alphabetical order. So when I extends AT_Database class into AT_CRUD its never found.
This is just because php loads AT_CRUD first than AT_Database so either I have to instantiate the class into or to use something like dependancy injection as #prehfeldt mention in his comment.

namespaces and class extends

Im trying to figure out how namespaces works in PHP, but havent really been lucky
Hope somebody could tell me what Im doing wrong here :)
code
require_once 'Vatcode.php';
$Vatcode = new \resource\Vatcode();
Vatcode.php
namespace resource;
require_once Ini::get('path/class').'/Resource.php';
class Vatcode extends Resource {
public function __construct(){
echo 'works!';
}
}
Rescource.php
namespace resource;
class Resource {
}
error
Fatal error: Class 'resource\Ini' not found in Vatcode.php
it's just a problem of namespace.
Your class Vatcode is in namesapce ressource. If, in the file of VatCode declaration you use nameofclas::... or new nameofclass() it will try to get the class in namespace ressource.
If you want to use the class Ini inside your document you have two solutions :
first give the full qualified name :
require \namespace\of\ini\Ini::get('path/class').'/Resource.php';
second using the "use" keyworld before using the get method :
use \namespace\of\ini\Ini;
require_once Ini::get('path/class').'/Resource.php';
In any case, if Ini is in "no namespace" (global namespace is the accurate word) you just has to use the solutions I gave you but only with \Ini instead of \namespace\of\ini\Ini

Categories