简体   繁体   中英

Using PhpSpreadsheet in Codeigniter without Composer

How I can use PhpSpreadsheet (new version of PHPExcel) but without install Composer.

I trying to use with Third_party but print an error like this:

"Fatal error: Class 'PhpOffice\\PhpSpreadsheet\\Spreadsheet' not found in /web/application/third_party/PhpOffice/PhpSpreadsheet/Spreadsheet.php on line 16"

¡Ayudaaaa!

I have a project where I have successfully used Symfony's deprecated Psr4ClassLoader: https://github.com/symfony/class-loader/blob/master/Psr4ClassLoader.php

Using this classloader is great if you need to do PSR4 style autoloading.

As an example:

require_once FCPATH . 'Psr4ClassLoader.php';
$loader = new Symfony\Component\ClassLoader\Psr4ClassLoader();
$loader->addPrefix('Skunkbad\Console', FCPATH . 'vendor/skunkbad/console/src');
$loader->register();

In that example, I am using a Console class, and I get to declare the namespace, and the location of the directory that the namespace is from.

$c = new Skunkbad\Console\Console('ChromePhp');
$c->log([1,2,3,4,5]);

Now I can load the Console class, and in this case I am passing in "ChromePhp" as a constructor parameter. Then I proceed to call the log method on my console object.

In your case, since the namespaced class is PhpOffice\\PhpSpreadsheet\\Spreadsheet, then you'd probably do something like this:

require_once __DIR__ . '/path/to/Psr4ClassLoader.php';
$loader = new Symfony\Component\ClassLoader\Psr4ClassLoader();
$loader->addPrefix('PhpOffice\PhpSpreadsheet', FCPATH . 'vendor/phpoffice/phpspreadsheet/src');
$loader->register();

And then use it like:

$x = new PhpOffice\PhpSpreadsheet\Spreadsheet();

Please understand, I don't know the specifics of working with your Spreadsheet class, but I'm showing you how you can use it without Composer. You're probably going to have to play around with the path to the package, and perhaps the namespace itself.

This is the class I use from: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md (I modified it a bit)

<?php
if (!defined('BASEPATH')) {
    exit('No direct script access allowed');
}

/**
 * An example of a general-purpose implementation that includes the optional
 * functionality of allowing multiple base directories for a single namespace
 * prefix.
 *
 * Given a foo-bar package of classes in the file system at the following
 * paths ...
 *
 *     /path/to/packages/foo-bar/
 *         src/
 *             Baz.php             # Foo\Bar\Baz
 *             Qux/
 *                 Quux.php        # Foo\Bar\Qux\Quux
 *         tests/
 *             BazTest.php         # Foo\Bar\BazTest
 *             Qux/
 *                 QuuxTest.php    # Foo\Bar\Qux\QuuxTest
 *
 * ... add the path to the class files for the \Foo\Bar\ namespace prefix
 * as follows:
 *
 *      <?php
 *      // instantiate the loader
 *      $loader = new \Example\autoloader_psr4;
 *
 *      // register the autoloader
 *      $loader->register();
 *
 *      // register the base directories for the namespace prefix
 *      $loader->addNamespace('Foo\Bar', '/path/to/packages/foo-bar/src');
 *      $loader->addNamespace('Foo\Bar', '/path/to/packages/foo-bar/tests');
 *
 * The following line would cause the autoloader to attempt to load the
 * \Foo\Bar\Qux\Quux class from /path/to/packages/foo-bar/src/Qux/Quux.php:
 *
 *      <?php
 *      new \Foo\Bar\Qux\Quux;
 *
 * The following line would cause the autoloader to attempt to load the
 * \Foo\Bar\Qux\QuuxTest class from /path/to/packages/foo-bar/tests/Qux/QuuxTest.php:
 *
 *      <?php
 *      new \Foo\Bar\Qux\QuuxTest;
 */
class autoloader_psr4
{

    /**
     * An associative array where the key is a namespace prefix and the value
     * is an array of base directories for classes in that namespace.
     *
     * @var array
     */
    protected $prefixes = array();

    /**
     * Register loader with SPL autoloader stack.
     *
     * @return void
     */
    public function register()
    {
        spl_autoload_register(array($this, 'loadClass'));
    }

    /**
     * Adds a base directory for a namespace prefix.
     *
     * @param string $prefix The namespace prefix.
     * @param string $base_dir A base directory for class files in the
     * namespace.
     * @param bool $prepend If true, prepend the base directory to the stack
     * instead of appending it; this causes it to be searched first rather
     * than last.
     * @return void
     */
    public function addNamespace($prefix, $base_dir, $prepend = false)
    {
        // normalize namespace prefix
        $prefix = trim($prefix, '\\') . '\\';

        // normalize the base directory with a trailing separator
        $base_dir = rtrim($base_dir, DIRECTORY_SEPARATOR) . '/';

        // initialize the namespace prefix array
        if (isset($this->prefixes[$prefix]) === false) {
            $this->prefixes[$prefix] = array();
        }

        // retain the base directory for the namespace prefix
        if ($prepend) {
            array_unshift($this->prefixes[$prefix], $base_dir);
        } else {
            array_push($this->prefixes[$prefix], $base_dir);
        }
    }

    /**
     * Loads the class file for a given class name.
     *
     * @param string $class The fully-qualified class name.
     * @return mixed The mapped file name on success, or boolean false on
     * failure.
     */
    public function loadClass($class)
    {
        // the current namespace prefix
        $prefix = $class;

        // work backwards through the namespace names of the fully-qualified
        // class name to find a mapped file name
        while (false !== $pos = strrpos($prefix, '\\')) {

            // retain the trailing namespace separator in the prefix
            $prefix = substr($class, 0, $pos + 1);

            // the rest is the relative class name
            $relative_class = substr($class, $pos + 1);

            // try to load a mapped file for the prefix and relative class
            $mapped_file = $this->loadMappedFile($prefix, $relative_class);
            if ($mapped_file) {
                return $mapped_file;
            }

            // remove the trailing namespace separator for the next iteration
            // of strrpos()
            $prefix = rtrim($prefix, '\\');
        }

        // never found a mapped file
        return false;
    }

    /**
     * Load the mapped file for a namespace prefix and relative class.
     *
     * @param string $prefix The namespace prefix.
     * @param string $relative_class The relative class name.
     * @return mixed Boolean false if no mapped file can be loaded, or the
     * name of the mapped file that was loaded.
     */
    protected function loadMappedFile($prefix, $relative_class)
    {
        // are there any base directories for this namespace prefix?
        if (isset($this->prefixes[$prefix]) === false) {
            return false;
        }

        // look through base directories for this namespace prefix
        foreach ($this->prefixes[$prefix] as $base_dir) {

            // replace the namespace prefix with the base directory,
            // replace namespace separators with directory separators
            // in the relative class name, append with .php
            $file = $base_dir
                . str_replace('\\', '/', $relative_class)
                . '.php';

            // if the mapped file exists, require it
            if ($this->requireFile($file)) {
                // yes, we're done
                return $file;
            }
        }

        // never found it
        return false;
    }

    /**
     * If a file exists, require it from the file system.
     *
     * @param string $file The file to require.
     * @return bool True if the file exists, false if not.
     */
    protected function requireFile($file)
    {
        if (file_exists($file)) {
            require $file;
            return true;
        }
        return false;
    }
}

Usage:

I store the class in libraries and load it like a regular library.

$this->load->library('autoloader_psr4');
$this->autoloader_psr4->register();
$this->autoloader_psr4->addNamespace('Noodlehaus', APPPATH . 'third_party/config');
$this->autoloader_psr4->addNamespace('Cake\Filesystem', APPPATH . 'third_party/Filesystem');

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM