Included class inside another class is not declared PHP - php

I have the following __construct of a selfmade class;
public function __construct($ip, $user, $pass, $product) {
$this->_ip = $ip;
$this->_user = $user;
$this->_pass = $pass;
$this->_product = $product;
$this->ssh = new Net_SSH2($this->_ip);
if (!$this->ssh->login($this->_user, $this->_pass)) {
return 'Login Failed';
}
$this->sftp = new Net_SFTP($this->_ip);
if (!$this->sftp->login($this->_user, $this->_pass)) {
return 'Login Failed';
}
}
Now the problem is that it says Net_SSH2 and Net_SFTP is not declared, but I have included those classes at the page, im not sure, but can it be that I have to pass those classes into this class instead of just calling them?
If yes, how do I do that?

A better solution is to use autoload.
function __autoload($class_name) {
require_once $class_name . '.php';
}
Now, when you ask for a new class, it will be auto loaded.
Try this.

Have you included those classes using a require, include or an autoload function?
If you haven't, make sure the files in which those classes are defined are loaded.
Now, we need to check for the namespace.
At the top of the Net_SFTP, is there a namespace [SOMETHING]? If there is, you must refer to the fully qualified class name, or use this class.
An example:
<?php
namespace VendorName\BundleName;
class Net_SFTP {
....
}
?>
Now, in order to use this class, we must do one of the following:
<?php
use VendorName\BundleName\Net_SFTP;
...
$this->ssh = new Net_SFTP(...);
...
?>
Or, directly:
<?php
...
$this->ssh = new VendorName\BundleName\Net_SFTP(...);
...
?>

Related

How to extend PHP class in mulitple files and mark every extend in namespace?

I have the following code:
File: class.engine.php (The Main Engine of the website)
<?php
namespace Core;
class Engine {
}
File class.errors.php (The Error trigger if something happens, customized errors)
<?php
namespace Core\Errors;
class Errors {
public function TrigerError($e)
{
die($e);
}
}
File class.mysqli.php (The database connector)
<?php
namespace Core\MySQLiDrv;
class MySQLiDrv {
public $db = null;
public function __construct($database) {
$connector = mysqli_connect($database[0], $database[1], $database[2], $database[3]);
if(!$connector)
{
return new TrigerError("1");
}
}
}
File index.php (Where everything runs)
<?php
include("engine/class.engine.php");
include("engine/class.errors.php");
include("engine/class.mysqli.php");
$engine = new Engine();
$db = new MySQLiDrv(array("localhost", "user", "pass", "db"));
I want to extend Engine class with many multiple files and I want them to be in namespace, how can I do that properly, because I can't trigger the error in this case of the code.
And is it important in this case of code to use namespaces defined as something for easy use?
Your main issue as I see it is the lack of the USE statement and the fact that TrigerError is a method and not a class.
To fix these:
namespace Core\MySQLiDrv;
use Core\Errors\Errors;
class MySQLiDrv {
public $db = null;
public function __construct($database) {
$connector = mysqli_connect($database[0], $database[1], $database[2], $database[3]);
if(!$connector)
{
return (new Errors)->TrigerError("1");
}
}
}
Full working code:
namespace Core{
class Engine {
}
}
namespace Core\Errors{
class Errors {
public function TrigerError($e)
{
die($e);
}
}
}
namespace Core\MySQLiDrv{
use Core\Errors\Errors;
class MySQLiDrv {
public $db = null;
public function __construct($database) {
//$connector = mysqli_connect($database[0], $database[1], $database[2], $database[3]);
//if(!$connector)
//{
return (new Errors)->TrigerError("1");
//}
}
}
}
//default global namesapce
namespace {
use Core\Engine;
use Core\MySQLiDrv\MySQLiDrv;
$engine = new Engine();
$db = new MySQLiDrv(array("localhost", "user", "pass", "db"));
}
Output
1
Sandbox
The only real difference here is that when you use multiple namespaces in a single file (sandbox) you have to enclose the code with {}. You can remove those if these are separate files. Well that and I cant use the DB functions in the sandbox, but that is irrelevant in this example because we want to trigger the error.
However as said in the comments, I would look into Autoloading and Exceptions both of which will help you here.
I have an autoloader on github you can play around with if you want, it's similar to what Composer uses/does. Composer is just more standardized.
Autoloadig basically uses a combination of the namespace and class to find the file at run time (when the class is instantiated). So there are some naming conventions to be aware of, for example take your class Core\Errors\Errors this should be located in Core/Errors/Errors.php The namespace and the file path should be the same. What this does is you can eliminate all the include statements and this loads the files only when needed auto-magically.

How to use PSR-4 in methods with PHP

Excuse me guys I am trying to use PSR-4 into my PHP project until now I have only one problem; If I only use classes
<?php namespace backend\controllers;
class Conexion
{
public function __construct() {
echo "hi";
}
}
and after in other file I put this it works fine
<?php
require_once __DIR__.'/vendor/autoload.php';
use backend\controllers\Conexion as Conexion;
$user = new backend\controllers\Conexion;
but if I try to change in the first block code by this:
<?php namespace backend\controllers;
class Conexion
{
public function __construct() {
$conexion = new mysqli('localhost','mysql','root','');
if($conexion) {
echo "1";
} else {
echo "0";
}
}
}
I get that following error
Fatal error: Class 'backend\controllers\mysqli' not found in
C:\xampp\htdocs\master-pure-php\app\backend\controllers\DataBaseController.php
on line 9
But I need to use a named method inside a class but I don't know how to do it.
Thanks in advance
As you can see - it's looking for mysqli under 'backend\controllers\mysqli'
A Quick fix...
Change
$conexion = new mysqli('localhost','mysql','root','');
to
$conexion = new \mysqli('localhost','mysql','root','');
The mysqli class is defined in the global namespace; in order to use it you could put this in your source code (at the top of your script):
use mysqli;

define class globally in withut require include

I want to define a class globally, so if I create a page this , it works
<?php
$cl = new MyOwnClass();
?>
How can I do that ?
You shoulod look into Autoloading Classes: http://www.php.net/manual/en/language.oop5.autoload.php
class classname
{
public function publicfuntioname($testvar) {
$this->testvar = $testvar;
}
}
Now include this file any where
$obj= new classname();
$obj->publicfuntioname("another value");

Lazy load class in PHP

I want to lazy load class but with no success
<?php
class Employee{
function __autoload($class){
require_once($class);
}
function display(){
$obj = new employeeModel();
$obj->printSomthing();
}
}
Now when I make this
function display(){
require_once('emplpyeeModel.php');
$obj = new employeeModel();
$obj->printSomthing();
}
It works but I want to lazy load the class.
__autoload is a standalone function not a method of a class. Your code should look like this:
<?php
class Employee{
function display(){
$obj = new employeeModel();
$obj->printSomthing();
}
}
function __autoload($class) {
require_once($class.'.php');
}
function display(){
$obj = new Employee();
$obj->printSomthing();
}
UPDATE
Example taken from the php manual:
<?php
function __autoload($class_name) {
include $class_name . '.php';
}
$obj = new MyClass1();
$obj2 = new MyClass2();
?>
Change Employee a bit:
class Employee {
public static function __autoload($class) {
//_once is not needed because this is only called once per class anyway,
//unless it fails.
require $class;
}
/* Other methods Omitted */
}
spl_autoload_register('Employee::__autoload');
First if all it's better to use spl_autoload_register() (check the note in php's manual for autoloading).
Then back to your problem; only if the display() function is in the same directory as the employeeModel this will work. Otherwise, use absolute paths (see also include() and include_path setting

Cannot find Class with PHP Namespace

I posted some questions previously regarding the use of Namespaces in PHP and from what I got, this example code I have below should be working.
However I am getting errors when I try to use Namespace in PHP like this. Here is the first error when running the code below as is...
Fatal error: Class 'Controller' not found in E:\Controllers\testing.php on line 6
E:\Controller\testing.php File
<?php
use \Controller;
include('testcontroller.php');
$controller = new Controller;
$controller->show();
?>
E:\Controller\testcontroller.php File
<?php
use \Library\Registry;
namespace Controller
{
class Controller
{
public $registry;
function __construct()
{
include('E:\Library\Registry.class.php');
$this->registry = new Registry;
}
function show()
{
echo $this->registry;
echo '<br>Registry was ran inside testcontroller.php<br>';
}
}
}
?>
E:\Library\Registry.class.php File
<?php
namespace Library\Registry
{
class Registry
{
function __construct()
{
return 'Registry.class.php Constructor was ran';
}
}
}
?>
As you can see I tried to make it as simple as possible just to get the Namespace part working. I have tried different variations and cannot seem to figure it out.
Even when using use statement, you need to specify the namespace of the class you are trying to instantiate. There are a lot of examples here: http://www.php.net/manual/en/language.namespaces.importing.php
To understand it better, I will describe to you how it works. In your case, when you do use \Controller, the whole Controller namespace becomes available to you, but not the classes that are in this namespace. So, for example:
<?php
include('testcontroller.php');
use \Controller;
// Desired class is in namespace!
$controller = new Controller\Controller();
// Error, because in current scope there is no such class
$controller = new Controller();
$controller->show();
?>
Another example:
testcontoller.php:
<?php
namespace Some\Path\To\Controller;
class Controller
{
function __construct()
{
}
function show()
{
echo '<br>Was run inside testcontroller.php<br>';
}
}
?>
testing.php:
<?php
include('testcontroller.php');
use \Some\Path\To\Controller;
// We now can access Controller using only Controller namespace,
// not Some\Path\To\Controller
$controller = new Controller\Controller();
// Error, because, again, in current scope there is no such class
$controller = new Controller();
$controller->show();
?>
If you wish to import exactly the Controller class, you need to do use Controller\Controller - then this class will be accessible in your current scope.
Its not that good idea to name the namespace, like the class, because it is confusing (and I think this is what happens here). There moment you define the alias via use Controller this referenes to either a class \Controller, or the namespace \Controller, but your class, because it is within the namespace, is named \Controller\Controller 1
use Controller;
$class = new Controller\Controller;
or
$class = new \Controller\Controller;
or
use Controller\Controller;
$class = new Controller;
The idea is, that the moment you try to access a class with its relative name it tries to map the "first part" against any alias defined using use (remeber use MyClass is the same as use MyClass as MyClass. The thing after as is the alias).
namespace MyNamespace\MyPackage\SomeComponent\And\So\On {
class MyClass {}
}
namespace Another {
use MyNamespace\MyPackage\SomeComponent; // as SomeComponent
$class = new SomeComponent\An\So\On\MyClass;
}
As you can see PHP finds SomeComponent as the first part and maps it against the SomeComponent-alias the line above.
You can read more about it in the manual about namespaces.
1 Its called "Full-qualified classname", if you name a class with its complete name.
When you put a class Controller in the namespace Controller, then you have to reference it that way:
$controller = new Controller\Controller();
\Controller would be a class in the global (default) namespace, i.e. as if you used no namespace at all.
Strangely I have found that in my example code from the Question above, if I change all the Namespace's that are defined to something like MyLibrary so it would be like this code below...
E:\Library\Registry.class.php File
<?php
namespace MyLibrary
{
class Registry
{
function __construct()
{
echo 'Registry.class.php Constructor was ran';
}
}
}
?>
Then when I use use MyLibrary\Registry; in another file, I am able to access it how I had planned...
$this->registry = new Registry;
The reason this is very strange to me is this now makes a class name appear to be a Namespace as well. So I would not need to set a Namespace to 'MyLibrary\Library' to access the Registry instead I would do it like I showed in this answer to be able to access it with just calling the name of the class.
I hope this makes sense and helps someone else. I will not accept this as the answer as I am hoping someone with more know-how will come in and post a better Answer with explanation
try
<?php
use \Library\Registry;
namespace Controller;
class Controller
{
public $registry;
function __construct()
{
include('E:\Library\Registry.class.php');
$this->registry = new Registry;
}
function show()
{
echo $this->registry;
echo '<br>Registry was ran inside testcontroller.php<br>';
}
}
?>
and
<?php
namespace Library\Registry;
class Registry
{
function __construct()
{
return 'Registry.class.php Constructor was ran';
}
}
?>
First off, I believe you are using composer or composer is initialised in your project. If so, check composer.json file for your autoload, psr-4 definition. For example, if the root of your application is "App", then in your psr-4, you should be doing "autoload": { "psr-4": { "App\\": "./" } },
Furthermore, remember to clear composer cache and dump-autoload from the terminal as follows:
composer clear-cache
composer dump-autoload

Categories