PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Friday, May 20, 2022

[FIXED] Why does class autoloading not work for a package required using "repositories.package"?

 May 20, 2022     autoload, composer-php, php     No comments   

Issue

Consider two scenarios:

In the first the library is loaded from Github, composer.json looks like this:

{
    "require": {
        "revenuewire/ach-file": "*"
    }
}

composer libraries are downloaded with this command:

php composer update

PHP code:

<?php
require '../composer/vendor/autoload.php';
$achFileHeaderRecord = new \RW\ACH\FileHeaderRecord([
    // Required
    \RW\ACH\FileHeaderRecord::IMMEDIATE_DESTINATION => ' 123456789',
    \RW\ACH\FileHeaderRecord::IMMEDIATE_ORIGIN      => '1234567890',
    \RW\ACH\FileHeaderRecord::DESTINATION_NAME      => 'DESTNAME',
    \RW\ACH\FileHeaderRecord::ORIGIN_NAME           => 'Orig Name',
    // Optional
    \RW\ACH\FileHeaderRecord::FILE_DATE             => new DateTime(),
    \RW\ACH\FileHeaderRecord::FILE_ID_MODIFIER      => 'A',
    \RW\ACH\FileHeaderRecord::REFERENCE_CODE        => '',
]);
?>

This code will run successfully.

But when I try to load the exactly same library from Gitlab, composer.json looks like this:

{
    "repositories": [
      {
        "type": "package",
        "package": {
          "name": "mygitlab/ach-file",
          "version": "1.2",
          "type": "package",
          "source": {
              "url": "https://mygitlab.ca/mygitlab/ach-file.git",
              "type": "git",
              "reference": "master"
          }
        }
      }
    ],
    "require": {
        "mygitlab/ach-file": "*"
    }
}

And now run the same code I get this error:

PHP Fatal error: Uncaught Error: Class 'RW\ACH\FileHeaderRecord' not found

This is caused because the library is not autoloaded. It can be solved by adding this line, to load it manually:

require '../composer/vendor/aptpayapi/ach-file/bootstrap.php';

So in the case it is loaded as external package it does not read/execute the library's composer.json

{
    "name": "revenuewire/ach-file",
    "type": "library",
    "description": "Create and read ACH Payment files",
    "homepage": "https://github.com/revenuewire/ach-payment-file",
    "license": "Apache-2.0",
    "authors": [
        {
            "name": "Matthew Casiro",
            "email": "mattcasiro@gmail.com"
        }
    ],
    "autoload": {
        "psr-4": {
            "RW\\": "src/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "RW\\Tests\\": "tests/"
        }
    },
    "config": {
        "platform": {
            "php": "7"
        }
    },
    "require": {
        "ext-ssh2": "*",
        "ext-bcmath": "*"
    },
    "require-dev": {
        "phpunit/phpunit": "^6.5"
    }
}

Is it possible to force autoload of externally loaded packages?


Solution

Your problem is that by using a package key for that repository, you are telling composer "read the package information from here, do not read the hosted composer.json". And since the package settings are almost bare, dependencies are not resolved and autoloader not generated.

The only thing that happens is that composer clones the repo within your vendor, then you are on your own.

You could add an autoload section to your current package key, as shown here. This way you could at least have the autoloader correctly generated.

But note that recursive dependency resolution will not be dealt with, which might leave you with other issues.

For that you could replicate the require part of the original composer.json within the package setting... but this is not smart. The package key is meant for packages that do not support Composer, so you can force them into supporting it within your application. You'd end with something like this:

{
  "repositories": [
    {
      "type": "package",
      "package": {
        "name": "mygitlab/ach-file",
        "version": "1.2",
        "type": "package",
        "autoload": {
          "psr-4": {
            "RW\\": "src/"
          }
        }, 
         "require": {
                "ext-ssh2": "*",
                "ext-bcmath": "*"
            },
        "source": {
          "url": "https://mygitlab.ca/mygitlab/ach-file.git",
          "type": "git",
          "reference": "master"
        }
      }
    }
  ],
  "require": {
    "mygitlab/ach-file": "*"
  }
}

Frankly, I wouldn't recommend this for a forked composer package. If what you want is use a fork of an existing package, do not use the package key at all.

Simply add the repository configuration, and require the forked package by its original name (revenuewire/ach-file in this case). Replace the version by dev-master (or whatever branch you use to hold your fork), and voilĂ , everything will work as usual because the library will be required as a regular composer package.

{
 "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/yivi/ach-file"
        }
    ],
    "require": {
        "revenuewire/ach-file": "dev-master"
    }
}



Answered By - yivi
Answer Checked By - Marilyn (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing