I am trying to use this composer package with a new project I am working on https://packagist.org/packages/activecollab/activecollab-sdk. However when i try and create a new class I keep getting the following errors.
Fatal error: Class 'ActiveCollab\Client' not found
The file that is throwing this error looks like this.
require "vendor/autoload.php";
new ActiveCollab\Client;
Which is just being used to test if the files are being loaded in properly. The composer.json of the file which I am trying to use looks like such. And I have a feeling the problem is in this file but I can't figure out what.
stuff...
"autoload": {
"psr-0": {
"ActiveCollab\\": "ActiveCollab"
}
}
...stuff
Also looking at the autload_namespaces.php file it is being generated as such.
<?php
// autoload_namespaces.php #generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'ActiveCollab' => array($vendorDir . '/activecollab/activecollab-sdk/ActiveCollab'),
);
I have used psr-0 in some composer packages of my own and everything looks to be right except maybe the camel case in the namespace but i don't see this as being disallowed in the php proposal for psr-0.
Thanks for any help this has been driving me crazy.
The thing is: You cannot simply add a composer.json file with a random autoloading configuration and hope that it works - it actually has to match the naming scheme you are using. That is what this project got wrong, and nobody tested it. Which probably means nobody uses this library, and you can expect no support from the creators due to lack of interest.
But let's see how they react on my pull request to get things back to working again.
The composer config looks fine: Is it just the case that you omitted the leading \ from your class name?
new \ActiveCollab\Client;
You'll need that if your code is inside another namespace, as it will load it relative to the current namespace.
EDIT: I've just checked out that library, and even with the above fix, the autoloader wasn't quite working. The autoloader may also be broken due to the composer.json file for the library specifying a PSR0 autoloader, but using ".class.php" extensions (not PSR0 compatible). An autoload.php file is included with the library, so if you just require that file, you should be able to use the classes:
require 'vendor/activecollab/activecollab-sdk/ActiveCollab/autoload.php';
After doing this, I was able to use the class.
Related
In YII2 Framework
Path of File is root\vendor\yiisoft\yii2-httpclient\Client.php
Namespace defined in above mentioned file is - namespace yii\httpclient;
Now when I use this namespace in other file while setting up Google ReCaptcha
by writing "use yii\httpclient\Client"
then I am getting error "Class yii\httpclient\Client" not found
So I want to know whether namespaces are path dependent ? or is there a routing file or htaccess..etc where I can define the actual path of namespaces used in project, which YII2 compiler will refer to locate the file / class ?
Namespaces themselves are not dependent on file path.
But you are probably mistaking what use clause does.
If you have this line in file:
use yii\httpclient\Client;
It doesn't mean that the class is loaded. It only tells parser that you mean yii\httpclient\Client every time you use Client class in that file.
PHP has something called autoload to make sure you don't have manually require files for each class you are using. Autoloaders are called every time you are using some class if that class hasn't been loaded yet. When they are called they are given the class name and they check if they know how to load that class.
Now, even if the namespaces itself are not dependent on file path autoloaders usually uses those namespaces to decide where to look for the file containing that class.
And as Nigel Ren mentioned in comment, there exist PSR-4 recommendation how to choose namespace and file structure to make sure that autoloader will know where to look for class.
Yii2 projects usually uses 2 autoloaders.
The Yii's own autoloader and autoloader generated by composer.
Since your question is about class that comes from vendor\yiisoft\yii2-httpclient the autoloader generated by composer.
If you check the composer.json file in that package you can see that it has autoloader section with psr-4 key. That tells composer that when it generates its autoloader it should be set to look for any class from yii\httpclient namespace in src folder of that package.
To make sure the composer's autoloader is working properly you have to go through following steps:
The yiisoft\yii2-httpclient package should be installed by composer.
If you need to regenerate composer's autoloader you can run:
composer dump-autoload
The composer autoloader must be included in your application's entry point (usually /web/index.php or /yii files).
Check if those files have this line:
// in case of /web/index.php
require(__DIR__ . '/../vendor/autoload.php');
//in case of /yii
require(__DIR__ . '/vendor/autoload.php');
I was wondering, I am currently trying to change my programming style to work with composer and its package system (my god why didn't I use it sooner?) but I was wondering I am trying to work following the PSR-4 standard.
And got the following php file
<?php
require_once(__DIR__ . '/vendor/autoload.php');
$class = new vendorname\packagename\classname;
$example = new vendorname\packagename\subpackage\classname2;
Is that good practice to use with composer and the PSR-4 standard?
Where the the classes are existing in:
- /vendor
-- /vendorname
--- /packagename
--- /src
---- classname.php
---- /subpackage
----- classname2.php
I am currently thinking it is, but I just want to make sure that I am using it correctly according to the PSR-4 standard :-).
Typically that is the way to go, but some packages use different namespaces (mainly packages that need to have legacy support, for as far as I have encountered). Therefore after you composer require the package and it's installed, you should check the files for the namespaces that are used. But yes, you are right, because the way you say it is how it's typically done.
Also usually the package's readme/website has some examples on how to construct their objects.
Example: The Monolog logger package has a file /vendor/monolog/monolog/src/Monolog/Logger.php that is in the Monolog namespace, not in the Monolog\Monolog\Src\Monolog namespace. Just be sure to check it, but most of the times examples on the package maintainer/owner's website will tell you how to use the package. In this example the readme on Github tells you how the package is used.
Most of packages include readme referring it's namespace. you can access classes using that namespace. if you can't found you can check from 'your_project_root/vendor/vendor_name/package_name/composer.json'.
"autoload": {
"psr-4": {"Monolog\\": "src/Monolog"}
},
For this example 'Monolog' is the namespace and this is the best way to follow psr standards.
<?php
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
// create a log channel
$log = new Logger('name');
$log->pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING));
// add records to the log
$log->warning('Foo');
$log->error('Bar');
You can see all this standards in https://www.php-fig.org/psr/
Additionally you can check how this packages loaded in 'autoload_psr4.php' located in
'your_project_root/vendor/composer/autoload_psr4.php'
when you run composer require, composer update or composer dump-autoload command. this file will updated.
New to PHP!
I have /var/www/html/index.php requiring json-schema from https://github.com/justinrainbow/json-schema
downloaded from git and moved JsonSchema folder to /var/www/html
the following in index.php gives Fatal error: Class 'JsonSchema\Constraints\Constraint' not found
require "JsonSchema/Validator.php";
use JsonSchema\Validator;
$validator = new JsonSchema\Validator();
$validator->check(json_decode($data), json_decode($schema));
if I include Constraint.php, it throws out another error. am missing some basics here. what is the proper way to use an external library?
thanks!
If you look in the project root, then there's a special file called composer.json wherein you will find on line 46 the namespace autoloader.
"autoload": {
"psr-4": { "JsonSchema\\": "src/JsonSchema/" }
},
When you install your project with composer, then this will generate a file called autoload.php which once included in your script will allow you to access all of the classes. Otherwise you are doomed to requiring each class one by one.
Furthermore, requiring each class is really inefficient on memory usage and runtime, so composer's autoload.php uses spl_autoload_register which is even better because it only loads the classes when they're actually called. Otherwise if you require a ton of classes and don't use all of them, then it's just a waste of resources and slows things down.
First thing you will need is composer
wget http://getcomposer.org/composer.phar
Usually people will use composer for downloading and including packages like this one as a new project dependency.
php composer.phar require justinrainbow/json-schema:~2.0
But since you've already cloned the source code because you want to actually develop this package, then you can simply generate the autoloader with:
php composer.phar dump-autoload
So your script should look like this:
require __DIR__ . '/vendor/autoload.php';
use JsonSchema\Validator;
$validator = new JsonSchema\Validator();
$validator->check(json_decode($data), json_decode($schema));
I'm hoping someone can spot what I've forgotten to do. Here are my steps:
Downloaded and unpacked the ZendFramework-2.3.5 into /usr/share.
Updated include_path in my php.ini file to include '/usr/share/ZendFramework-2.3.5/library' per the INSTALL.md, and restarted Apache to confirm the path is set (now ".:/usr/share/php:/usr/share/ZendFramework-2.3.5/library").
Created a test script in my web document root (using the class 'CamelCaseToUnderscore' as an example):
use Zend\Filter\Word\CamelCaseToUnderscore;
$filter = new CamelCaseToUnderscore();
echo $filter->filter('BigsAndLittles');
...and I get the fatal error "class 'zend\filter\word\camelcasetoseparator' not found".
In order to do use Zend classes like this, do I need to do some additional configuration or create an autoloader or something to find them? Seems like this should have worked. If I include the CamelCaseToUnderscore.php file in a require_once statement, then I get a fatal error that it's parent class doesn't exist (CamelCaseToSeparator.php). What am I missing?
You can use require 'Zend/Mvc/Application.php' to test if your include path is correct, but you will need an autoloader:
http://framework.zend.com/manual/current/en/modules/zend.loader.standard-autoloader.html.
You can find an example here (lines 18-20):
https://github.com/zendframework/zf2/blob/master/demos/Zend/Feeds/consume-feed.php
I strongly suggest using composer as it will save you a lot of time troubleshooting your include paths, but it also allows you manage version better. It makes it easier for other developers and to deploy your code.
Starting with composer is very easy, just install it and create composer.json:
https://getcomposer.org/doc/01-basic-usage.md#composer-json-project-setup
Run:
composer require zendframework/zendframework
Composer will download all libraries to vendor folder and will generate an autoloader, all you have to do is to include
require 'vendor/autoload.php';
https://getcomposer.org/doc/01-basic-usage.md#autoloading
Most popular PHP frameworks use composer for managing dependencies:
https://github.com/zendframework/zf2/blob/master/composer.json
https://github.com/symfony/symfony/blob/2.7/composer.json
I'm currently developing on Windows with WampServer and have Composer working (with OpenSSL), with Propel installed without issue, and everything seems to work fine. However, my project now needs to make use of the Equal Nest Behaviour found here.
I thought this would allow me to use the propel behaviour. In my schema.xml I have the following snippet:
<table name="friend">
<behavior name="equal_nest">
<parameter name="parent_table" value="user" />
</behavior>
</table>
But when I run propel-gen sql I get the error:
[phingcall] Unknown behavior "equal_nest"; make sure you configured the propel.be
havior.equal_nest.class setting in your build.properties
The documentation says:
Then, if you don't use Composer, or an autoloader in your application, add the following configuration to your build.properties or propel.ini file:
Making me presume that I didn't have to put in the build.properties file. However, putting it in gives me the following error:
PHP Fatal error: Class 'EqualNestParentBehavior' not found in C:\home\movesleag
ue.com\vendor\craftyshadow\propel-equalnest-behavior\src\EqualNestBehavior.php o
n line 74
I wasn't sure if that was something to do with autoloading not working or namespaces (my schema has a namespace, but I get this same error when removing it too).
My composer.json file looks like this:
{
"require": {
"craftyshadow/propel-equalnest-behavior": "dev-master"
}
}
Note: I did have Propel in there itself, but as the equalnest behaviour requires it itself I'm just letting that do its job.
So, what's the correct way to use Propel behaviours with Composer, and if I'm doing it right, why do I see the errors above?
Updates
I added this line to the top of EqualNestBehaviour.php:
include __DIR__ . DIRECTORY_SEPARATOR . 'EqualNestParentBehavior.php';
And the SQL seems to be generated correctly without errors. However, changing that file doesn't seem clever to me! Could it be a problem with autoloading? Is there anything you can think of that I can do to test that?
I can confirm that using Equal Nest Behaviour in my actual Propel code works fine, using functions like addFriends() - this is with the above changes still in place.
In my autoload_namespaces.php file I have the following:
<?php
// autoload_namespaces.php generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
);
This is an autoloading issue.
Please check that you have
propel.behavior.equal_nest.class = vendor.craftyshadow.propel-equalnest-behavior.src.EqualNestBehavior
in your build.properties (for Propel).
Please check that the composer generated autoloader file is included during the bootstrap process of your application. Composer generates a "vendor/autoload.php" file. If you include it, then you get autoloading for free. And everything installed by Composer is found automatically.
require 'vendor/autoload.php';