Phpspreadsheet: php autoload without Autoloader.php

Created on 20 Oct 2016  路  13Comments  路  Source: PHPOffice/PhpSpreadsheet

set_include_path('classes/');
spl_autoload_extensions('.php');
spl_autoload_register();

This requires the use of the letters in the file names in lowercase.

Most helpful comment

In my opinion all PHP scripts developers should provide a non-composer option. There are real reasons why composer cannot be used. For example, if you are selling/distributing CMS plugins that use these scripts, you cannot expect your users to all have or know how to use composer.

All 13 comments

Why don't you want to use the provided bootstrap/autoloader?

Use something like

<?php

require_once __DIR__ . '/path/to/PhpSpreadsheet/src/Bootstrap.php';

// your code here

Or even better use Composer (with a manually declared package for now).

The project I am working on requires that composer not be used.
And this work-a-round no longer works.
Thoughts?

No real, sustainable solution. You could try to run composer locally and somehow package everything together yourself. But you'll be on your own...

But the real question is why can't you use composer ?

Is there a reasonable way to only have composer be used when called from within a function in a class?

I have found that a majority of other composer/packagist software nodes can easily be included without requiring composer.

I assume you are talking about using composer autoload mechanism only in from certains methods. I suppose it could technically be possible to register the autoload, do your thing and then un-register it somehow. But that seems like a very very slippery slope...

can easily be included without requiring composer

That does not make sense to me. I either don't understand your context, or you are mis-using composer somehow. But if you are able to not use composer with other packages, why don't you do the same thing for PhpSpreadsheet ?

To autoload without composer:
1) Create an autoloader.php file for PhpSpreadsheet:

<?php
spl_autoload_register(function ($class_name) {
    $preg_match = preg_match('/^PhpOffice\\\PhpSpreadsheet\\\/', $class_name);

    if (1 === $preg_match) {
        $class_name = preg_replace('/\\\/', '/', $class_name);
        $class_name = preg_replace('/^PhpOffice\\/PhpSpreadsheet\\//', '', $class_name);
        require_once(__DIR__ . '/path/to/PhpSpreadsheet/' . $class_name . '.php');
    }
});

2) Create Psr.php (few required interfaces, i.e. "PSR-16: Common Interface for Caching Libraries"):
Copy the code from here, that is:

<?php
namespace Psr\SimpleCache;

interface CacheInterface {...}

/*...*/
interface CacheException
{
}

/*...*/
interface InvalidArgumentException extends CacheException
{
}

3) Create an autoloader.php for Psr (required interface):

<?php
spl_autoload_register(function ($class_name) {
    $preg_match = preg_match('/^Psr\\\/', $class_name);

    if (1 === $preg_match) {
        require_once(__DIR__ . '/path/to/Psr.php');
    } else if (false === $preg_match) {
        assert(false, 'Error de preg_match().');
    }
});

4) Include the autoloaders in your code:

<?php
// Your code
require_once('/path/to/Psr/autoloader.php');
require_once('/path/to/PhpSpreadsheet/autoloader.php');
// Your code

This worked for me.

Composer is the only official and supported solution to use PhpSpreadsheet. Custom made solutions such as the one mention in this thread are strongly advised against. Not using composer will give you more work to set up, and potential issues to maintain. Think twice before choosing the more complicate path for your projects.

Again, those solutions should not be used.

@animike Thank you for sharing your work around. Like others I'm not in a position to use composer at the moment since it would require additional scope for changing deploy scripts, installing it on servers, etc. I like composer and use it on other projects but the effort of wiring it into a legacy project isn't trivial.

Migrating from PHPExcel to PhpSpreadsheet went smooth otherwise. So +1 to the maintainers for not rearranging the classes/methods!

In my opinion all PHP scripts developers should provide a non-composer option. There are real reasons why composer cannot be used. For example, if you are selling/distributing CMS plugins that use these scripts, you cannot expect your users to all have or know how to use composer.

I guess I will have to use another library.

@PowerKiKi You assume the user has access to composer. I'm on a shared server and don't have access to composer and support won't install PHPOffice.

@Animike You're a life saver. Worked perfectly. Got it running locally with no composer.

animike's solution really is not the best option. It already broke in v1.4.0 because of 1b96c95a4414940b4bb08637e8ec0edd94f5cb0f and in 1.6.0 because of a5eb64c77f6c1a53159e50d80dbed935d00bd8e6. And it will break again in the future without any notice. Maintenance will be a pain when it should be very straightforward if using composer. This is because composer is not only doing autoloading, it also manages dependencies. And PhpSpreadsheet dependencies will be changed without any notice according to whatever best serve the library.

If you cannot, or don't want to, run composer on your production server (which is a reasonable use-case), then you should run composer locally, package everything that composer installed for you together with your project and upload that to your production server.

But you should be aware of platform requirements for production server that will not be checked by composer. That means PHP version and PHP extensions must be manually checked to avoid surprises.

Basically it's https://stackoverflow.com/a/49326968/37706.

I am locking this thread, because this is the final solution to the problem, and it should be seen by as many people as possible.

Was this page helpful?
0 / 5 - 0 ratings