Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Autoloader: Use a base dir #66

Open
NanoSector opened this issue Jan 9, 2015 · 6 comments
Open

Autoloader: Use a base dir #66

NanoSector opened this issue Jan 9, 2015 · 6 comments

Comments

@NanoSector
Copy link
Contributor

Right now the autoloader freaks out if it doesn't find the file as it expects every class to be loaded from within the phpbot404.php file. If you want to initialise a class from a command, it won't work; the autoloader will try to load an inexisting file and crash.

Solution: Set a 'dir' => dirname(FILE) var in config.php and make the autoloader use that as prefix.

@JackBlower
Copy link

Can you give an example? You can easily load classes as long as the structure adheres to the autoloader's folder structure, which is Classes/<namespace>/classname.php.

If you look at line 36 on Autoloader.php (https://github.com/super3/IRC-Bot/blob/master/Classes/Autoloader.php#L36) then you can see it uses the Class directory:

 $filename = __DIR__ . '/' . str_replace( '\\', '/', $class ) . '.php';

Something that needs to change is that the autoloader shouldn't throw an Exception if the file isn't loaded, as that stops other auto-loaders from being registered and used as a lower priority than the one defined here (composer etc)... This is something that I have changed in my new re-write of the bot (soon to have an initial release on my [ElvenSpellmaker's] fork).

If you really can't load the class, then you could always use require and require a new auto-loader and register it within the command.

@NanoSector
Copy link
Contributor Author

Yes, there's the problem as well. DIR points at the directory the file currently in context resides in. So if you have Bot.php, which is in Classes/Library/IRC, DIR is Classes/Library/IRC.

ETA: DIR = _ _ DIR _ _ without spaces. I suck at Markdown.

@JackBlower
Copy link

The autoloader is perfectly fine, it points to _Classes/_ which is where all classes should be?

It points to where the autoloader.php is,not where the current script is..?

@NanoSector
Copy link
Contributor Author

Nevermind, wasn't thinking. Either way, if the autoloader is fine, please explain why this doesn't work:

09.01.2015 - 20:57:58     [ LOG ]   :NanoSector!~Yoshi2889@simplemachines/support/NanoSector PRIVMSG #NanoPlayground :!!exec $this->bot->removeCommand('Ping');
09.01.2015 - 20:57:58     [ LOG ]   Requesting privileges for host ~Yoshi2889@simplemachines/support/NanoSector...
09.01.2015 - 20:57:58     [ LOG ]   Success; proceeding with command.
09.01.2015 - 20:57:58     [ LOG ]   Running command "$this->bot->removeCommand('Ping');"
09.01.2015 - 20:57:58     [ INFO ]  The following Command was removed from the Bot: "Ping".
09.01.2015 - 20:58:33     [ LOG ]   :NanoSector!~Yoshi2889@simplemachines/support/NanoSector PRIVMSG #NanoPlayground :!!exec $this->bot->reAddCommand('Ping');
09.01.2015 - 20:58:33     [ LOG ]   Requesting privileges for host ~Yoshi2889@simplemachines/support/NanoSector...
09.01.2015 - 20:58:33     [ LOG ]   Success; proceeding with command.
09.01.2015 - 20:58:33     [ LOG ]   Running command "$this->bot->reAddCommand('Ping');"

Fatal error: Uncaught exception 'Exception' with message 'File: "/mnt/data/IRC Bot/Classes/Library/IRC/ReflectionClass.php" not found.' in /mnt/data/IRC Bot/Classes/Autoloader.php:40
Stack trace:
#0 [internal function]: Autoloader::load('Library\\IRC\\Ref...')
#1 /mnt/data/IRC Bot/Classes/Library/IRC/Bot.php(338): spl_autoload_call('Library\\IRC\\Ref...')
#2 /mnt/data/IRC Bot/Classes/Command/Exec.php(18) : eval()'d code(1): Library\IRC\Bot->reAddCommand('Ping')
#3 /mnt/data/IRC Bot/Classes/Command/Exec.php(18): eval()
#4 /mnt/data/IRC Bot/Classes/Library/IRC/Command/Base.php(159): Command\Exec->command()
#5 /mnt/data/IRC Bot/Classes/Library/IRC/Bot.php(363): Library\IRC\Command\Base->executeCommand(Array, '#NanoPlayground', ':NanoSector!~Yo...')
#6 /mnt/data/IRC Bot/Classes/Library/IRC/Bot.php(283): Library\IRC\Bot->executeCommand('#NanoPlayground', 'Exec', Array, ':NanoSector!~Yo...')
#7 /mnt/data/IRC Bot/Classes/Library/IRC/Bot.php(190): Library\IRC\Bot->main()
#8 /mnt/data/IRC Bot/phpbot404.php(92): Library\IRC\Bot->co in /mnt/data/IRC Bot/Classes/Autoloader.php on line 40
09.01.2015 - 20:58:33     [ LOG ]   Shutdown function called, closing log...
    public function reAddCommand($commandName)
    {
        $reflector = new ReflectionClass($commandName);

        $command = $reflector->newInstanceArgs($args);

        $this->addCommand($command);
    }

@ElvenSpellmaker
Copy link
Collaborator

I assume you're trying to use the built in ReflectionClass from PHP. I suggest you go and read about namespaces which explains all about how to use them.
In order to access a class in the global namespace you'll need to prepend the class with a backslash to show you're accessing a global class and not in the current namespace. E.g.:

namespace Foo;

// Looks for Foo\Exception
$foo = new Exception;

// Looks for Exception in the global namespace.
$foo = new \Exception;

// If Exception is not defined in Foo\Exception then you can alias it using a `use` statement
// Notice the lack of \ in front of the Exception as use statements always start from the gobal namespace.
use Exception;

// Now looks for \Exception, not \Foo\Exception
$foo = new Exception.

Generally people import/alias classes from different namespaces to make it cleaner code and to be able to switch the class out with just editing the use statement, rather than everywhere it might be in the code.

To fix this then you can do one of two things:

  1. Import the ReflectionClass at the top of your file using a use statement (Recommended).
  2. Put a backslash before the ReflectionClass statement to show the intent to use the global namespace.

Also the bot doesn't use any use statements throughout at the moment and that should be changed before the bot gets any bigger really.

(You can also alias to other class names and more with namespaces).

Check out: http://php.net/manual/en/language.namespaces.php
Specifically: http://php.net/manual/en/language.namespaces.importing.php

@NanoSector
Copy link
Contributor Author

I just copied over the quoted code from the bot, same file; I don't see why
it would work once and not twice.
On 10 Jan 2015 14:28, "ElvenSpellmaker" [email protected] wrote:

I assume you're trying to use the built in ReflectionClass from PHP. I
suggest you go and read about namespaces which explains all about how to
use them.
In order to access a class in the global namespace you'll need to prepend
the class with a backslash to show you're accessing a global class and not
in the current namespace. E.g.:

namespace Foo;// Looks for Foo\Exception$foo = new Exception;// Looks for Exception in the global namespace.$foo = new \Exception;// If Exception is not defined in Foo\Exception then you can alias it using a use statement// Notice the lack of \ in front of the Exception as use statements always start from the gobal namespace.use Exception;// Now looks for \Exception, not \Foo\Exception$foo = new Exception.

Generally people import/alias classes from different namespaces to make it
cleaner code and to be able to switch the class out with just editing the
use statement, rather than everywhere it might be in the code.

To fix this then you can do one of two things:

  1. Import the ReflectionClass at the top of your file using a use
    statement (Recommended).
  2. Put a backslash before the ReflectionClass statement to show the
    intent to use the global namespace.

Also the bot doesn't use any use statements throughout at the moment and
that should be changed before the bot gets any bigger really.

(You can also alias to other class names and more with namespaces).

Check out: http://php.net/manual/en/language.namespaces.php
Specifically: http://php.net/manual/en/language.namespaces.importing.php


Reply to this email directly or view it on GitHub
#66 (comment).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants