PHP how to import class with namespace - php

I have never used namespaces in PHP before and I cannot import some library classes that use them. I'm trying to use the wsdl2php library, here is the example code on how to use the library:
$generator = new \Wsdl2PhpGenerator\Generator();
$generator->generate(
new \Wsdl2PhpGenerator\Config(array(
'inputFile' => 'input.wsdl',
'outputDir' => '/tmp/output'
))
);
However, it doesnt matter where I put my php file that executes this code, it always throws class not found error, even if I include both classes with include or require, then the library class will throw class not found error, since it wants to use yet another library class.
Here is some directory tree for reference:
[src]
[Filter]
DefaultFilter.php
...
[Wsdl2PhpGenerator]
[Console]
Applicaton.php
...
...
Config.php
Generator.php
my_php_file_here.php
namespace declaration in Config.php: namespace Wsdl2PhpGenerator; How use is used in Config.php: use Wsdl2PhpGenerator\ConfigInterface;
From what I have seen, I have added the following to the start of my php file:
namespace Wsdl2PhpGenerator;
use Wsdl2PhpGenerator\Generator;
use Wsdl2PhpGenerator\Config;
With no success, I still get
Fatal error: Class 'Wsdl2PhpGenerator\Generator' not found in C:\kajacx\programming\PHP\EET\test\wsdl2phpgenerator-master\src\kappa.php on line 8 ($generator = new \Wsdl2PhpGenerator\Generator();)
So, how to make this work?

Just use:
require_once __DIR__ . '/vendor/autoload.php';
and composer will resolve the imports for you.
(tested with the same lib and it worked)

as as I just worked with the wsdl2php lib (cloned from github) and had the same issue, here is what I did to resolve it :
1) don't forget to launch composer install before all ...
2) Add require_once dirname( dirname(__FILE__) ) . '/vendor/autoload.php'; at the top of your php file.

Related

Using a composer script with a hyphen in the name?

I a'm trying to use the following script from Github: https://github.com/php-webdriver/php-webdriver
Installing with composer in "/mnt/hgfs/" was easy, but loading the class in a php file seems impossible
As you can see, there is a hyphen in the name, and i can't seem to load the class in any way. I have googled for a lot and tried many things, but same problem, either i get:
Trying to use the hyphen in namespace and use i get
PHP Parse error: syntax error, unexpected '-', expecting '{' in
/mnt/hgfs/test.php on line 3
Replacing hyphen with underscore, or just removing it i get:
PHP Fatal error: Uncaught Error: Class
'php_webdriver\WebDriver\Remote\DesiredCapabilities' not found in
/mnt/hgfs/test.php:10
This is how my code looks (/mnt/hgfs/test.php):
namespace php_webdriver\WebDriver;
require 'vendor/autoload.php';
use php_webdriver\WebDriver\Chrome\ChromeOptions;
use php_webdriver\WebDriver\Chrome\ChromeDriver;
use php_webdriver\WebDriver\Remote\DesiredCapabilities;
use php_webdriver\WebDriver\Remote\RemoteWebDriver;
$host = 'http://localhost:4444/wd/hub'; // this is the default
$capabilities = DesiredCapabilities::htmlUnitWithJS();
{
$options = new ChromeOptions();
$options->addArguments(array(
'--disable-extensions',
'--no-sandbox',
'--headless',
'--no-proxy-server'
));
$capabilities = DesiredCapabilities::chrome();
$capabilities->setCapability(ChromeOptions::CAPABILITY, $options);
$capabilities->setPlatform("Linux");
}
$driver_spec = RemoteWebDriver::create($host, $capabilities, 600000, 600000);
How should I load this class?
There are a couple of things wrong here:
namespace php_webdriver\WebDriver;
You shouldn't be trying to add your code to the webdriver namespace. For a test script you don't need your own namespace. You can probably delete this line.
As for:
require 'vendor/autoload.php';
use php_webdriver\WebDriver\Chrome\ChromeOptions;
use php_webdriver\WebDriver\Chrome\ChromeDriver;
use php_webdriver\WebDriver\Remote\DesiredCapabilities;
use php_webdriver\WebDriver\Remote\RemoteWebDriver;
I get the impression you're not 100% familiar with how PSR-4 / autoloading works. The namespace is mapped to a code directory by autoload.php, and the two don't necessarily have to have the same naming structure.
Take a look at the composer.json in the webdriver project, and pay attention to the PSR-4 section.
"Facebook\\WebDriver\\": "lib/" tells you that anything in the lib directory is to be considered as being in the Facebook\WebDriver namespace.
Try
require 'vendor/autoload.php';
use Facebook\WebDriver\Chrome\ChromeOptions;
use Facebook\WebDriver\Chrome\ChromeDriver;
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\Remote\RemoteWebDriver;

Composer autoload is called but loaded nothing

Project structure
/Test
composer.json
composer.lock
index.php
nfe.xml
vendor/
autoload.php
(more files)
PHP Code
And I am trying a snipped which I found at the library's README on github
<?php
require_once 'vendor/autoload.php';
// var_dump( get_declared_classes() );
echo 'a';
$nfeProc = NFePHPSerialize::xmlToObject(file_get_contents('nfe.xml'));
echo 'b';
//Capturando CNPJ do emitente
$cnpjEmitente = $nfeProc->getNFe()->getInfNFe()->getEmit()->getCNPJ();
echo $cnpjEmitente;
Results
But I am getting the following error:
PHP Fatal error: Class 'NFePHPSerialize' not found in /var/www/html/Test/index.php on line 7
PHP Stack trace:
PHP 1. {main}() /var/www/html/Test/index.php:0
Finally I have uncommented the var_dump( get_declared_classes() ); just to know whether something from the library nfephp-serialize (for tax purposes) is loaded but I found nothing.
Initialization
To init the Test directory, I have issued the following command:
$ composer require jansenfelipe/nfephp-serialize
How to solve?
What is missing is the path associated with the NFePHPSerialize class. It is JansenFelipe\NFePHPSerialize.
You may want to use the class NFePHPSerialize with its namespace, as so:
<?php
require 'vendor/autoload.php';
use JansenFelipe\NFePHPSerialize\NFePHPSerialize;
or simply write:
$nfeProc = JansenFelipe\NFePHPSerialize\NFePHPSerialize::xmlToObject(file_get_contents('nfe.xml'));
How I found the namespace?
You may want to search for the NFePHPSerialize class in the /vendor directory... and find the namespace statement, which is:
namespace JansenFelipe\NFePHPSerialize;
So, the class is available with namespace\class as so:
$var = new JansenFelipe\NFePHPSerialize\NFePHPSerialize(...);
But you can improve this by inserting the use statement as so:
<?php
use JansenFelipe\NFePHPSerialize\NFePHPSerialize;
// some code...
$var = new NFePHPSerialize(...);
I hope this helps you! :)

How can I call a function in a php class?

This is a sample code:
sample code
I want to call it in another page:
include 'root of class file';
$r = new ImagineResizer();
I got this error:
Fatal error: Class 'ImagineResizer' not found in C:\WampDeveloper\Websites\example.com\webroot\images.php on line 13
Also call the function:
$r->resize('c:/test1.jpg', 'c:/test2.jpg');
As seen in your sample code the class is located in another namespace :
<?php
namespace Acme\MyBundle\Service;
use Symfony\Component\HttpFoundation\File\File;
use Imagine\Image\ImagineInterface;
use Imagine\Image\BoxInterface;
use Imagine\Image\Point;
use Imagine\Image\Box;
class ImagineResizer {
//-- rest of code
}
To use a class in another namespace you need to point out where the file is :
First include the class (manual or with autoloading)
Then u can create an instance in 2 ways. First way with the use-keyword
use Acme\MyBundle\Service\ImageResizer;
$object = new ImageResizer();
Or point to the class absolute :
$object = new \Acme\MyBundle\Service\ImageResizer();
Hopefully, this will help you out some:
Make sure you include the actual file - not just the folder where it lies.
Make sure that the file you're calling the class from uses the same namespace as your class file. If it doesn't, you have to call the class using the full namespace.
Profit.
The namespaces really had my patience go for a spin when I started using them, but once you're used to it it's not too hard. I would recommend using an autoloader though. It's a bit of a hassle to set up, but once it's done it helps out a bunch.
Namespaces: http://php.net/manual/en/language.namespaces.php
Autoloader: http://php.net/manual/en/function.spl-autoload-register.php

In php namespaces do I need to require each file

If I'm using namespace and for example I have the following directory tree
Test/someclass.php
Test/someotherclass.php
can I simply do
use \Test\someotherclass
or I need first to do
require 'Test/someotherclass.php'
and then I can actually use that class
because currently when I do that I get the following error
Fatal error: Class 'Test\someOtherClass' not found in
C:\xampp\htdocs\test\Test\someClass.php on line 10
As said in the comments the namespace and the use statement don't load anything by default.
But you can use an autoloader based on namespace. You have a standard called psr-0 for autoload.

How to properly use Universal Class Loader?

I'm trying to use Universal Class Loader functionality from Phalcon into my project, however I can't get it working.
Here is how i've implemented into my app (using registerClasses).
index.php:
//...
$loader->registerClasses(
array(
"Commons" => "library/classes/CommonsClass.php"
)
);
$loader->register();
sampleController.php:
public function doAction()
{
$cc = new Commons();
}
And when I execute the controller, it throws me this exception:
Fatal error: Class 'Commons' not found in C:\the\path\to\phalcon_app\app\controllers\SomeController.php on line 63
The Phalcon Documentation just say that you need to register a class and call it in your funcion. There is something I've missed?
Ps.: The library folder is not registered anywhere (don't know if its needed), and it is in the same path as controllers, views, etc (/app/).
You should probably check your directory structure.
given:
mah_app/app/config/loader.php
mah_app/library/classes/Commons.php
I would expect this to work:
// loader.php
$loader->registerClasses(
array(
"Commons" => __DIR__ . "/../../library/classes/Commons.php"
)
)->register();
// works with $loader->registerDirs() for sure
Also, I would also suggest using namespaces and/or matching file name with class name.
Had the same problem. I commented out the namespace declaration inside the class and it worked. Version 2.0.3.

Categories