Composer autoload is called but loaded nothing - php

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! :)

Related

Calling a method from outside class with dependencies PHP

Problem:
I have an index.php file which has several composer dependencies.
Inside the index.php file i'm trying to call the static method from the outside class in a different php (let's say auth.php) file like this:
/*creating a class instance*/
$var = new AuthClass();
/*accessing an outside class method*/
$var = AuthClass::checkTime($tokenCode);
The issue is the checkTime method inside the class requires a composer dependency as well, which isn't inherited, although the file is located in the same folder as index.php and index.php is included.
PHP Fatal error: Uncaught Error: Class 'Token' not found
I've tried everything - from adding require_once/include 'index.php' to copying the composer autoload to auth.php outside and inside the AuthClass code, but nothing works, i'm still getting the same error.
Additional code:
index.php
require __DIR__ . '/src/vendor/autoload.php';
$argument1 = $_GET['argument1'];
$tokenCode = $_GET['tokenCode'];
include 'config/database.php';
include 'objects/program1.php';
include 'auth.php';
use ReallySimpleJWT\Token;
use Carbon\Carbon;
$secret = "somesecret";
if (($_SERVER['REQUEST_METHOD']) == "GET") {
if ($_GET['url'] == "bankquery") {
if($tokenCode===NULL){
echo "no correct token provided";
print($results);
} else {
$results = Token::validate($tokenCode, $secret);
if ($results = 1){
$var = new AuthClass();
$var = AuthClass::checkTime($tokenCode);
} else {
echo "no correct token provided";
}
}
} else {
echo "some GET other query";
}
?>
auth.php
// loading composer
require __DIR__ . '/src/vendor/autoload.php';
//loading my index.php file
include 'index.php';
//using composer dependencies
use ReallySimpleJWT\Token;
use Carbon\Carbon;
class AuthClass{
public static function checkTime($tokenCode){
// getting payload from token code by accessing the composer dependency method in a class Token
$received = Token::getPayload($tokenCode);
return $received;
}
}
?>
Need help, guys.
You're using AuthClass before it was defined - try move include 'index.php'; line at the end of the file.
You should also include vendor/autoload.php only once - you don't need to repeat this in every file, just make sure that it is included at the top of the entry file which handles request.
But this is more like a result of design problem. You should define AuthClass in separate file and avoid any additional side effects in it - file should only define class. This is part of PSR-1 rules:
Files SHOULD either declare symbols (classes, functions, constants, etc.)
or cause side-effects (e.g. generate output, change .ini settings, etc.)
but SHOULD NOT do both.
Since you're already using autoloader from Composer it should be relatively easy to register your own autoloading rules, so Composer's autoloader will take care about classes autoloading.
If at this point you're still getting Class 'X' not found, you probably did not installed some dependency or your autoloading rules are incorrect.
The simplest solution would be to include your own code in the composer autoloading.
The composer website tells you how to do it.
You don't need to require the composer files yourself and composer handles everything for you.
The PSR-4 tells you how to namespace your code to use Namespacing.

PHP how to import class with namespace

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.

'Alias is never used' PHPStorm error message within my PHP file

I am following the installation instructions here to install PHP RAML Parser
I run composer install and created the index.php below but it isn't working, I get an error:
Class 'Raml\ParseConfiguration' not found in /cygdrive/c/src/myapp/Raml/Parser.php on line 83
When I hover over the line use \Raml\Parser I get the PHPStorm warning message (Alias never used)
My index.php:
<?php
require ('Raml/Parser.php');
use \Raml\Parser; // Alias \Raml\Parser is never used
$parser = new \Raml\Parser();
Can anyone suggest what I've done wrong?
Provided that the file Raml/Parser.php contains:
namespace Raml;
class Parser {}
You can either do this:
require ('Raml/Parser.php');
$parser = new \Raml\Parser();
or this:
require ('Raml/Parser.php');
use \Raml\Parser;
$parser = new Parser();
use imports a class/interface/trait into your current namespace and allows to use a shorter name instead of the fully qualified, backspaced name. It also allows to switch to a different class by only changing the use statement, and not every name reference in the whole class, but this benefit is very small because using PHPStorm brings some powerful renaming abilities itself.

php / composer not loading interface

I've banged my head against the wall for 3/4 of a day now and just can't see the error of my ways.
I'm creating (or trying to!) a simple package that consists of a couple of classes and 1 interface. This is in github at https://github.com/dnorth98/victoropsnotifier
Basically though, there's the following directory structure:
victoropsnotifer
src
Signiant
VictorOpsNotifier
Transport.php
VictorOpsNotifier.php
Transport is very simple:
<?php
namespace Signiant\VictorOpsNotifer;
interface Transport
{
// must POST the $message to the VictorOps REST endpoint
public function send(Messages\Message $message);
}
and the beginning of VictorOpsNotifier is
<?php
namespace Signiant\VictorOpsNotifer;
use GuzzleHttp\Client;
class VictorOpsNotifer implements Transport
{
protected $endpoint_url;
:
:
The problem comes when I try to instantiate a new object using
<?php
require_once 'vendor/autoload.php';
use Signiant\VictorOpsNotifier\Messages\CustomMessage;
use Signiant\VictorOpsNotifier\VictorOpsNotifier;
$voConfig = ['routing_key' => 'test',
'endpoint_url' => 'https://goo'];
$voHandle = new VictorOpsNotifier($voConfig);
I get back
PHP Fatal error: Interface 'Signiant\VictorOpsNotifer\Transport' not found in /tmp/djn/tests/vendor/signiant/
victoropsnotifier/src/Signiant/VictorOpsNotifier/VictorOpsNotifier.php on line 8
PHP Stack trace:
PHP 1. {main}() /tmp/djn/tests/test.php:0
PHP 2. spl_autoload_call() /tmp/djn/tests/test.php:12
PHP 3. Composer\Autoload\ClassLoader->loadClass() /tmp/djn/tests/test.php:0
PHP 4. Composer\Autoload\includeFile() /tmp/djn/tests/vendor/composer/ClassLoader.php:301
PHP 5. include() /tmp/djn/tests/vendor/composer/ClassLoader.php:412
What on EARTH am I missing? Composer is finding the package ok from my github repo and everying is in the vendor folder and looks ok. It looks like the namespaces match...so for some reason, it's just not loading the Transport.php file containing the interface.
It seems to be just a typo:
namespace Signiant\VictorOpsNotifer;
^ no `i` in here
but
use Signiant\VictorOpsNotifier\VictorOpsNotifier;
^ but here it is
same thing with the class name.
Also, you're declaring namespace Signiant as src/, but it's really src/Signiant
By the way, there's no need to declare this package as psr-0, better to use psr-4 insetad. Not a big deal, just for conformity.
P.S. The strange thing it was complaining about interface, while it shouldn't have to until it hit the class, and it certainly must not hit the class while there was a typo.
P.P.S You can easily avoid those typo errors by using a proper IDE, PHPStorm, for example. It would highlight name of the class as missing as long as there wre typos (and i don't even start talking about autocompletion).
class VictorOpsNotifer implements \Signiant\VictorOpsNotifer\Transport{}
try add namespace before your interface.

Error when using SplClassLoader

First off, I'm trying my hand using the following SplClassLoader -https://gist.github.com/221634
Here is my file structure:
/root/f1/f2/APS/Common/Group.php
/root/f1/f2/index.php
/root/f1/f2/SplClassLoader.php
Here is my test class called Group (Group.php)
namespace APS\Common;
class Group{
...
}
Here is the index.php file that is calling everything:
require "SplClassLoader.php";
$classLoader = new SplClassLoader('APS', 'APS/Common');
$classLoader->register();
I'm getting the following error:
Fatal error: Class 'Group' not found in /root/f1/f2/index.php on line 17
I've tried every conceivable combination when passing the namespace and path to the loader. It never works.
Update #1 - Line 17 in index.php:
16: use APS\Common;
17: $x = new Group();
Update #2 - Configuration info
Apache/2.2.15 (Red Hat)
PHP 5.3.3
Update #3 - I'm getting a different error message now.
The code in place:
require "SplClassLoader.php";
$classLoader = new SplClassLoader('APS', '/root/f1/f2');
$classLoader->register();
use APS\Common;
$x = new Common\Group();
Error message that I'm getting:
Warning: require(/f1/f2/APS/Common/Group.php): failed to open stream: No such file or directory in /root/f1/f2/SplClassLoader.php on line 133
When using the use statement (no pun intended), you simply create an alias for the used namespace or class. According to the PHP manual, use \Foo\Bar; is equivalent to use \Foo\Bar as Bar;.
So, in your case, you import the APS\Common namespace with the alias Common. This means that you can refer to the Group class within this namespace as Common\Group instead of APS\Common\Group. Without using the namespace alias (as you did), the classloader will expect the Group class to be in the global namespace (and expect the class to be stored in /root/f1/f2/Group.php).
Edit: Another possibility would be to simply put namespace \APS\Common; into your file. If you reference a class without a namespace specification (i.e. Group instead of \Group or \APS\Common), PHP will expect the class to be in the current namespace.
In my case, here is the solution that seems to work.
require "SplClassLoader.php";
$classLoader = new SplClassLoader('APS\Common', __DIR__);
$classLoader->register();
use APS\Common;
$x = new Common\Group();
I had to use the magic constant DIR for it to work. The second parameter seems to need to point to the physical path of the root of where the classes reside. Then, the namespace gets added to locate them in the file system.

Categories