I had a working composer package with a single files and a single class. So, now I'm trying to change the package so that it is more like SOLID.
I have a file structure like this...
PackageName.php
addresses.php
names.php
interfaces
names.php
addresses.php
When I use PHPSpec the methods in the main PackageName.php are getting validated but within one of the methods I have something like...
namespace blah\PackageName;
use blah\PackageName\ProcessNames;
class PackageName
{
public function formatData($user)
{
$place_holders = array();
$place_holders = ProcessNames::process_name($user, $place_holders);
$place_holders = ProcessAddresses::process_address($user, $place_holders);
return json_encode($place_holders);
}
}
which gives the error...
48 ! should do the address
exception [err:Error("Class 'blah\PackageName\ProcessNames' not found")] has been thrown.
The composer.json is like...
{
"name": "blah\PackageName",
"description": "Format data.",
"require": {
"nesbot/carbon": "^1.34",
"php": ">7.0.0"
},
"require-dev": {
"phpspec/phpspec": "^4.3"
},
"authors": [
{
"name": "me",
"email": "me#emailaddress.com"
}
],
"autoload": {
"psr-4": {
"blah\\PackageName\\": "src/",
"spec\\blah\\PackageName\\": "spec/"
},
"files": {
"src/interfaces/names.php",
"src/names.php"
}
}
}
I can't see how to include files in the package. I'm not sure I need the "files" part on composer.json but I'm trying to figure out how to do it. Any info much appreciated.
This is the same issue someone else had today! A simple error.
Replace:
namespace blah\PackageName;
with:
namespace blah;
The full class name includes the namespace and class name. So essentially your class was actually an instance of blah\PackageName\Packagename
Possibly take Packagename out of the composer.json, depending on your needs, and if you change that, remember to run composer dumpautoload
Related
im learning something about RedBeanPHP ORM and add the
code downloaded from http://www.redbeanphp.com/downloadredbean.php
to my project autoload using 'composer dump-autoload' command and
the configuration 'composer.json' in the root directory is:
{
"autoload": {
"classmap": [
"vendor/redbeanphp/src/rb.php",
"vendor/myowncode/src/Model.php"
]
}
}
on 'vendor/composer/installed.json' i put this:
[
{
"name": "gabordemooij/redbean",
"version": "5.4",
"require": {},
"autoload": {
"psr-4": {"RedBeanPHP\\": "src"}
}
},
"name": "myowncode/src",
"version": "1.0",
"require": {},
"autoload": {
"psr-4": {"MyCode\\": "src"}
}
}
]
and all works fine, at least until i try the example from the RedBean web
about 'Models' and the code:
<?php
require 'vendor/autoload.php';
class Model_Band extends RedBean_SimpleModel {
public function update() {
if ( count( $this->bean->ownMember ) >4 )
throw new Exception( 'Too many members!' );
}
}
results in error:
PHP Fatal error: Cannot declare class RedBeanPHP\RedException, because the name is already in use in /opt/lampp/htdocs/testing/vendor/redbeanphp/src/rb.php on line 8358
Fatal error: Cannot declare class RedBeanPHP\RedException, because the name is already in use in /opt/lampp/htdocs/testing/vendor/redbeanphp/src/rb.php on line 8358
but, if i dont use autoload and do this:
require 'vendor/redbean/src/rb.php';
class Model_Band extends RedBean_SimpleModel {
public function update() {
if ( count( $this->bean->ownMember ) >4 )
throw new Exception( 'Too many members!' );
}
}
it works, but i want that works with the autoload, i know, i can just open composer.json file and add the package name ("gabordemooij/redbean": "dev-master"), but i want to learn more about autoload and
get a good comprehension of whats wrong on my configuration/code.
The problem was the code from http://www.redbeanphp.com/downloadredbean.php its not
prepared for use with composer autoload, is some kind of amalgamation, all the code
in a single file, and i try downloading a release from:
https://github.com/gabordemooij/redbean/archive/v5.4.2.zip, i do the same process
to generate autoload, but we must edit the file loader on RedBeanPHP dir on the
release and change the REDBEANPHP_MAIN_DIR from phar://rb.phar/RedBeanPHP/
to vendor/redbean-5.4.2/RedBeanPHP/, i put the code on vendor/redbean-5.4.2,
and thats all problem solved :)
Here is my folder structure
in my package/index.php look like this
require_once 'vendor/autoload.php';
use HelloWorld\SayHello;
use Test\First;
//works fine
SayHello::world();
//returns classnot found error
First::sayTest();
In my composer.json' i've included the following.
"autoload": {
"psr-0": {
"HelloWorld": "src/"
}
}
But i got the following error in First::sayTest() line
Fatal error: Uncaught Error: Class 'Test\First' not found
But the class First.php exists under src\Test folder.
namespace Test;
class First
{
public static function sayTest()
{
echo 'test';
}
}
You only declared that one prefix resides in src. Add another one:
"autoload": {
"psr-0": {
"HelloWorld": "src/",
"Test": "src/"
}
}
Also note that when you are using namespaces, PSR-4 is better suited:
"autoload": {
"psr-4": {
"HelloWorld\\": "src/HelloWorld/",
"Test\\": "src/Test"
}
}
your composer.json contains some entry, which makes it load HelloWorld, but there is no such entry for the folder "Test".
Maybe it would help to copy your First.php to the HelloWorld-folder and change your reference in package.index.php.
Change composer.json to read:
"autoload": {
"psr-4": {
"": "src/"
}
}
Then run composer dump-autoload to regenerate vendor/autoload.php.
Read more about the autoload section of composer.json.
I have a Packagist package for composer, lwilson/onepage, with one PHP file. The file has one class, which contains one function. I have installed the package on my Web server, and I have a PHP file which is supposed to use it. I know that the composer autoloader is included properly, since I could use other composer libraries installed on the server. I get the following result:
Fatal error: Class 'OnePage\OnePage' not found in /home/photox952/public_html/onepage/test_onepage.php on line 6
test_onpepage.php (the file that uses the class):
<?php
require '../../vendor/autoload.php';
use OnePage\OnePage;
file_put_contents("index.php",OnePage::OnePage(json_decode(file_get_contents("cfg.json")),__DIR__));
?>
compiler.php (the file in the package):
<?php
namespace OnePage;
// This is licenced under the GNU GENERAL PUBLIC LICENSE. More info at: https://github.com/LeoWilson-XnD/lwilson_onepage/blob/master/LICENSE
class OnePage{
public static function OnePage($cfg,$dir){
$tmplt_u = "<?php if(\$_REQUEST['type']==\"{TYPE}\"&&\$_REQUEST['src']==\"{SRC}\"){header(\"Content-Type: {CT}\"); ?>{DATA}<?php } ?>";
$tmplt_c = "<?php if(\$_REQUEST['all']==\"{TYPE}\"){header(\"Content-Type: {CT}\"); ?>{DATA}<?php } ?>";
$res = "<?php /* This code is generated by the OnePage tool. Find out more here: https://github.com/LeoWilson-XnD/lwilson_onepage */ ?>";
$dir.=$cfg['dir'];
if($cfg['v']==1){
foreach($cfg['unique'] as $ka => $va){
foreach($cfg[$ka] as $kb => $vb){
$u = $tmplt_u;
$u=str_replace("{TYPE}",explode("/",$ka)[1],$u);$u=str_replace("{SRC}",$kb,$u);$u=str_replace("{CT}",$ka,$u);$u=str_replace("{DATA}",file_get_contents($dir.$vb),$u);
$res.=$u;
}
}
foreach($cfg['combine'] as $ka => $va){
$ds = "";
foreach($cfg[$ka] as $kb => $vb){
$ds.=file_get_contents($dir.$vb);
}
$u = $tmplt_c;
$u=str_replace("{TYPE}",explode("/",$ka)[1],$u);$u=str_replace("{CT}",$ka,$u);$u=str_replace("{DATA}",file_get_contents($dir.$vb),$u);
$res.=$u;
}
foreach($cfg['links'] as $key => $val){
$res = str_replace($val,$key,$res);
}
}
return $res;
}
}
?>
composer.json (the package's composer.json file):
{
"name": "lwilson/onepage",
"description": "This allows users to compile websites easily into one PHP file.",
"authors": [
{
"name": "Leo Wilson",
"email": "lwilson#xlww.net",
"homepage": "https://xlww.net/",
"role": "Developer"
}
],
"minimum-stability": "stable",
"version": "v1.0.0",
"homepage": "https://github.com/LeoWilson-XnD/lwilson_onepage",
"licence":"GPL-3.0",
"require": {
"php": ">=5.3.0"
},
"autoload": {
"psr-4": {
"": "/"
}
}
}
I apologize in advance if I'm missing something obvious.
I think you set the autoload wrong in composer. Try to create a folder named OnePage and put the file with the class in it. It must be named OnePage.php
Then set autoload like this
"autoload": {
"psr-4": {
"OnePage\\": "OnePage"
}
}
then run composer update from the shell. Then try running your php file again.
The OnePage.php file should be in folder /home/photox952/public_html/onepage/OnePage
I am new to using composer and psr-0. I have tried a small app using composer and psr-0. I have used namespace to load a particular class. When i call a class using composer vendor/autoload I am getting class not found error.
My composer.json file:/var/www/html/silexapp/composer.json
{
"require": {
"silex/silex": "~2.0",
"symfony/console": "~2.6"
},
"autoload": {
"psr-0": {
"MyApp": "/silexapp/app"
}
}
}
My composer vendor autoload file: /var/www/html/silexapp/vendor/autoload.php
<?php
// autoload.php #generated by Composer
require_once __DIR__ . '/composer' . '/autoload_real.php';
return ComposerAutoloaderInitf7241d907c173a8d77da0791cc918856::getLoader();
My class file name Underline.php: /var/www/html/silexapp/app/Tnq/Todo/Command/Underline.php
<?php
namespace MyApp\Tnq\Todo\Command;
class Underline{
public function add($a,$b){
return $result = $a+$b;
}
}
?>
My another class file name Bold.php: /var/www/html/silexapp/app/Tnq/Todo/Command/Bold.php
<?php
require_once "../../../../vendor/autoload.php";
//require_once "Underline.php";
use MyApp\Tnq\Todo\Command as tool;
echo "this is the index file to check namespace.";
$c = new tool\Underline();
echo "=============================";
echo "Addition : ".$c->add(2,2);
?>
I am getting "class not found error" in my bold.php class file, when I use autoload file. But when I directly included the underline class file, I am getting the output. Why it is not working when I use autoload?
Can anyone help me to find the issue?
The "key" should be a directory under the path you put as "value", that should be relative to your working directory. To look at it in a simple way, the namespace should map the directory structure; you are missing a MyApp directory.
If in your composer.json have:
"autoload": {
"psr-0": {
"MyApp\\": "app/"
}
}
Then you need a MyApp directory under app/. Try this:
composer.json:
// /var/www/html/silexapp/composer.json
{
"require": {
"silex/silex": "~2.0",
"symfony/console": "~2.6"
},
"autoload": {
"psr-0": {
"Tnq\\": "app/"
}
}
}
Underline.php:
<?php
// /var/www/html/silexapp/app/Tnq/Todo/Command/Underline.php
namespace Tnq\Todo\Command;
class Underline
{
public function add($a,$b)
{
return $result = $a+$b;
}
}
Bold.php:
<?php
// /var/www/html/silexapp/app/Tnq/Todo/Command/Bold.php
require_once "../../../../vendor/autoload.php";
use Tnq\Todo\Command as tool;
echo 'this is the index file to check namespace.' . PHP_EOL;
$c = new tool\Underline();
echo "=============================";
echo "Addition : ".$c->add(2,2);
In theory, that should works (not tested :) )
sources:
https://getcomposer.org/doc/04-schema.md#psr-0
http://www.php-fig.org/psr/psr-0/
I would like to use composer script to do some post installation such as copying files from bootstrap vendor folder to my web application public folder. I have a baby experience with PHP world and web application development.
I'm trying to learn doing this by following this tutorial
This is my directory structure*
This is my composer.json
{
"name": "Composer Script",
"description": "An example to demonstrate the use of Composer scripts",
"version": "1.0.0",
"require": {
"twitter/bootstrap": ">=3.0"
},
"scripts": {
"post-install-cmd": [
"ComposerScript\\Installer::postInstall"
],
"post-package-install": [
"/var/www/test/composer-script/install.sh"
]
}
}
This is ComposerScript\Installer.php
class Installer
{
public static function postInstall(Event $event)
{
$composer = $event->getComposer();
// do stuff
}
public static function postPackageInstall(Event $event)
{
$installedPackage = $event->getOperation()->getPackage();
// do stuff
}
public static function warmCache(Event $event)
{
// make cache toasty
}
}
After execute composer install I got this error
install.sh is empty at this moment
How to fix this error, and especially what is autoload?, I don't event know what keywords to search for please suggest me some reading.
Just in case someone stumbled again to this problem. Here is a spoon feed sample. :)
In a given scenario like this
We have to set on our composer.json to the ff. settings
"autoload": {
"psr-0": {
"ComposerScript\\Installer" : ""
}
},
"scripts": {
"post-package-update": [
"ComposerScript\\Installer::postPackageUpdate"
]
}
Then the content of Installer.php is
namespace ComposerScript;
use Composer\Script\Event;
class Installer
{
public static function postUpdate(Event $event)
{
$composer = $event->getComposer();
// do stuff
}
public static function postPackageUpdate(Event $event)
{
$packageName = $event->getOperation()
->getPackage()
->getName();
echo "$packageName\n";
// do stuff
}
public static function warmCache(Event $event)
{
// make cache toasty
}
}
Then executing php composer.phar update will work without warning.
The post-package-install value is relative to the location of the composer.json file. Do not use absolute location here.
Also, Composer's install scripts expect PHP, not sh!
Kongthap, I ran into the same problem and this is how I fixed it:
"require": {...},
"autoload": {
"psr-0": {
"Dphp": "src/"
}
},
"scripts": {...}
Dphp is the root namespace of my lib.
Hope it helps.
Sometimes the problem can be global packages are outdated, you can fix it by running the command composer global update before running composer install