Why can't I instantiate this class? - php

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.

Related

PHP namespace syntax

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 {
}

Namespace with extends or interface causes Fatal Error without autoloader

Why doesn't this work?
web/index.php (Not web/src/App/App.php)
<?php
namespace App;
// web/index.php
require_once __DIR__ . '/../vendor/autoload.php';
$app = new App();
class App extends \Silex\Application {
public function __construct()
{
parent::__construct();
echo 'Worked!';
}
}
I also tried namespace App {...}, no change. It throws this exception:
Fatal error: Uncaught Error: Class 'App\App' not found in /path/to/web/index2.php:8
Stack trace:
#0 {main}
thrown in /path/to/web/index2.php on line 8
As long as I remove the extends ... and the parent call part, it works. I also noticed interface does the same thing (trying to use Serializable). Is this an issue with the autoloader being confused? Is there a way to do this without putting the App\App class into a file in src\App\App.php?
Note: this is an exercise to build a single-file application with Silex, so "just put it in a file" isn't an answer. I want to know why this doesn't work, which has an answer.
The problem in your code is,
In namespace, You are initiating class object before it being declared and loaded. In your above code you are doing same thing,
1. You are initiating App class object which lies in App namespace
2. You are initiating class object at the moment class when is not yet declared(As it is defined below in your code).
In your above code, not even your loader be called. It will be called if you initiate App\App class object after its declaration. and If your loader does not work fine then afterwards you will possibly get this error.
Fatal Error: Silex\Application class not found
Please checkout some examples and findings.
Example 1 Here loader is expected to be called but not called, because you have registered after initialization of class($app = new App();).
Example 2 Here, calling class will look for autoloading class because here initialization takes place after registration of loader and declaration of class, which is probably answers your question.
Change your code with this to get it fix:
<?php
namespace App;
require_once __DIR__ . '/../vendor/autoload.php';
class App extends \Silex\Application {
public function __construct()
{
parent::__construct();
echo 'Worked!';
}
}
$app = new App();

Custom Exception not found in Cakephp3

I want to create and use a custom exception class in my CakePhp Application.
So I created a DuplicateConfigurationException.php with the following class skeleton:
<?php
namespace Cake\Exception;
class DuplicateConfigurationException extends Exception{
} ?>
I a controller, where I wish to raise the Exception, I added
use Cake\Exception\DuplicateConfigurationException;
and within a function I call
throw new DuplicateConfigurationException();
Following suggestions throughout the interwebs, I have tried to place the php file in the following locations, but neither of them seems to work:
src/Exception
src/Exceptions
src/Lib
src/Lib/Error
src/Lib/Error/Exceptions
I always get an error:
Error: Class 'Cake\Exception\DuplicateConfigurationException' not found
File /host/var/www/src/Controller/StructuresController.php
Line: 246
What else do I need to do to make Cake recognize my custom exception?
I'm well aware of Loading custom class in CakePHP3, but since this exception is not a separate library I would rather not place it within vendor?
A bit late but I think it might be useful for other users with the same question to have some further explanations.
In fact, with your solution, you rely on native PHP SPL Exception class located in global namespace.
To use Cake's basic Exception class, you missed to add
use Cake\Core\Exception\Exception;
in src/Exceptions/DuplicateConfigurationException.php for loading Cake Exception class constructor. See Cake's book
Your code is working because Cake is handling SPL exceptions the same way than its own Exception class. If you've wanted to go further with a custom handler for instance, it may have broken logic.
Note that class IniPermissionsException extends \Cake\Core\Exception\Exception {}; is also working. In this case, you must prepend \ as the root namespace when calling a class in an extends statement because you need to provide full namespace path.
To swim like a dolphin in Cake's namespaces, just go to API reference.
Full updated code for src/Exceptions/DuplicateConfigurationException.php :
<?php
namespace App\Exceptions;
use Cake\Core\Exception\Exception;
class DuplicateConfigurationException extends Exception {}
?>
Ok, after some fiddling I managed to get it working:
in src/Exceptions/DuplicateConfigurationException.php
<?php
namespace App\Exceptions;
class DuplicateConfigurationException extends \Exception{
} ?>
in the controller:
use App\Exceptions\DuplicateConfigurationException;
...
function somefunction(){
throw new DuplicateConfigurationException();
}
Apparently the namespace should be App\<Folder> and App\<Folder>\<Classname>, respectively.
And I had to prepend Exception with a backslash, since it is used in a namespaced context: http://www.php.net/manual/en/language.namespaces.global.php
Still, I'm not sure where the namespace conventions for CakePhp 3 are documented.

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?

request.CRITICAL: Uncaught PHP Exception Compile Error: Cannot declare class

I use the following two classes with the same name.
/src/AppBundle/Qrcode.php
namespace AppBundle\Qrcode;
use Endroid\QrCode\QrCode;
class Qrcode
{
And
/vendor/Endroid/.../Qrcode.php
namespace Endroid\QrCode;
use Endroid\QrCode\Exceptions\DataDoesntExistsException;
use Endroid\QrCode\Exceptions\VersionTooLargeException;
use Endroid\QrCode\Exceptions\ImageSizeTooLargeException;
use Endroid\QrCode\Exceptions\ImageFunctionUnknownException;
use ReflectionFunction;
class QrCode
{
on the dev it works well but not on the prod one as I receive the following error message:
request.CRITICAL: Uncaught PHP Exception
Symfony\Component\Debug\Exception\FatalErrorException: "Compile Error:
Cannot declare class AppBundle\Qrcode because the name is
already in use" at .../src/AppBundle/Qrcode.php line 8.
I don't understand why it doesn't work. The namespaces are different and
It works on the dev part...
Thanks
You need to differentiate class with alias because QrCode Class is loaded twice.
In, /src/AppBundle/Qrcode.php
namespace AppBundle\Qrcode;
use Endroid\QrCode\QrCode as EndroidQr // assign alias here to differnciate class
after this, new EndroidQr(); would instantiate a Endroid\QrCode\QrCode Class
Note:- If you want to load one class in a file who has same class name then you need to assign alias.
Hope it will help you :-)

Categories