There can be Only One Autoloader #72

Closed
Teqa opened this Issue Sep 27, 2012 · 64 comments

Comments

Projects
None yet

Teqa commented Sep 27, 2012

Custom Autoloader is disabled by default in Restler 3

Restler 3 is disabling all autoloaders and is using its own loader.
The function is even called: "thereCanBeOnlyOne"

There is a need for a autoloader. We use our own autoloader with a multi environment logic. This cannot be handled by a default one.

We understand the reason why the autoloader is disabled, to avoid conflicts.
However, by disabling the autoloader, one of the main features of Restler is compromised: "highly flexible".

Suggestion is to keep the current logic, and add an option to disable the feature. Another suggestion might be to white list autoloaders. But that might be too complicated.

@ghost ghost assigned nickl- Sep 27, 2012

Contributor

nickl- commented Oct 2, 2012

There can be only one! =)

Don't be alarmed by the name of this method, it is merely making a fun play at the Highlander saga, rest assured that your special autoloader whatever magic it performs was not disabled. I'll explain more but first I need to nip in the butt, before it becomes a vicious rumour, your accusation that the One And Only is incapable.

Hearsay:

This cannot be handled by a default [autoloader]

Fact:
The new Restler Autoloader is fully capable of handling any type of PHP class loading you can imagine and several I am sure you haven't even thought about yet.

If you find it lacking in any way or you see anything that we've missed please feel free to bring examples to the table and I'd be happy to fix anything that is broken or which limits you in any way. What I don't want is that you worry about it and loose any needless sleep, so lets try and put your mind to...

The bane of any php application is the Fatal error! If we are aiming to have more stable applications then we need to first address these as you can recover from the rest. If I accomplished one thing with the Autoloader it would be to never see this error again:

PHP Fatal error:  Cannot redeclare class

Which we accomplish by taking ownership of the class loading task. If you look a little closely you will notice that the other loaders were not disabled, instead they are kept in a queue, if for any reason you have not enable Autoloader to find the class through the myriad other solutions at your disposal, each autoloader will be given a chance to attempt loading the class in question before we finally mark it as "does not exist". This is still quicker than having 50 loaders fighting each other to do the same thing. As an added benefit, something not catered for elsewhere you cannot have duplicate autoloaders anymore no matter how frequently you register a particular function, this happens more often than you may think and the outcome is never pleasant.

Any subsequent requests will get the same answer from cache without having to think about it again, how often do you call class_exists on the same "non existent class name" only to attempt to discover it time and time again for no reason. What this also means is that the new Autoloader is gearing up to make class discovery obsolete. While ensuring that any class referenced will uniquely be associated with either:

  • a source file
  • a master class being aliased
  • a custom loader which has the sole capability of resolving this particular class (so be it)
  • or we can confidently say it really doesn't exist and looking for it again is not going to change this fact

Accomplishing not only reference integrity but sets the stage for our ultimate goal, to cache this discovery between requests, turning class discover into nothing more than a dictionary lookup, transparent across strategies, with no configuration required. It should be evident now why we need to seek out other loaders wanting to ruin the surprise. There can truly, be only one!

Now we're not claiming that it is perfect right out of the blacks, it will require more testing and we are expecting problems to arise. We therefor have deliberately chosen not to implement any cache adapters at this point as you may be aware that cache of any sorts can make problem solving... well a problem. Instead we specifically want Autoloader to get as much practice at collecting the cache definitions as possible. So you are encouraged to put it through its paces and I'd love to know if it is unworthy of this task in any way.

Needless to say we are ready to APC, Memcache, Redis, Elastic, File or database storage or any other flavours you'd prefer, without breaking a sweat.

Hearsay:

one of the main features of Restler is compromised: "highly flexible".

On the contrary this is the most flexible class loader ever conceived:

  • Uses the std php include path at your disposal
  • PSR-0 compliant old _ style and new namespaced style
  • Can load PEAR, Pyrus, Composer packages natively
  • Support namespace prefixing, reluctant to move to namespaces you can actually get away without declaring use statements just add prefix.
  • Class Aliasing, want to add a new adaptor to an existing factory but its looking for classe in namespace A\B\C no problem E\D\C == A\B\C
  • Map classes to source files directly, we even track multiple classes included by the same source file
  • Use your own autoloader that's fine

@Teqa Thank you for the opportunity to provide this brief introduction, I hope you are equally excited at the possibilities and eager to take it for a test drive. Looking forward to hear about your experiences, don't hesitate jump right in what's the worst that can happen right? =)

@nickl- nickl- closed this Oct 2, 2012

Contributor

nickl- commented Oct 2, 2012

Updated title to be easily referenced under closed issues

Teqa commented Oct 3, 2012

@nickl-
Thanks for explaining your thoughts.
We have discussed this in the team and we have mixed feelings about the way you look at things.
It is very good that you show enthousiasm on your work and that you are confident that the loader is a fine piece of art.

Howevere, we looked at the integration again and thee only way to get our autoloader to work is to disable the "spl_autoload_unregister" in "your" autoloader class.

The way we see it, is that Restler is a layer into our application. Many other layers are loaded via the controllers. Forcing us to use the Restler autoloader will force us to change the application as a whole, instead of only the restler layer. This is not even possible without a lot of work. But even if it was possible, we believe the software should not be linked into each other like that.

Forcing other parties to follow your standards might sound very reasonable, but that is why we mentioned in the first post "not very flexible". Maybe you have the best software in the world, that does not even matter. If you enforce it, this is far from flexible.

We have decided to uncomment the line and use RC2 for now.
If this is the way forward, we have to look at other framework or maintain our own fork.
As you notice, we do not even post our autoloader logic here. Because that is not the right discussion.
If we have misunderstood your explanation, we are happy to hear that. Overall the RC1/2 has been a great piece of work, so it would be very good to continue on this path.

Contributor

nickl- commented Oct 3, 2012

Just to be clear (once more) :

  • You are not forced to do anything!
  • The Autoloader can work with other loaders, by design.

Please stop making unvalidated claims that Restler is not flexible.

This is the pre-release phase and we expect problems to arise, we also expect that our community will help test the release candidates and by reporting their findings do their part, in the spirit of opensource, to contribute to the excellence of the product. We are willing, eager and committed to fix and address any problems which we can duplicate with your assistance. Unless you help us to help you I don't see how we are able to resolve this issue.

Be warned that Autoloader was designed to take ownership of autoloading and by simply uncommenting spl_autoload_unregister or anything else for that matter, without considering the design will have side effects. Since auto loading classes is at the core of the application it effects all other parts and we will not be able to help when problems unfold.

You are correct about one thing though, the posting of your logic and/or forking of Restler with or without changes are licensing issues and this is not the right discussion.

Marked unresolved with Blocker: Need more information from user to reproduce the problem.

@nickl- nickl- reopened this Oct 3, 2012

Teqa commented Oct 3, 2012

Hi @nickl-
Thanks for your answer.
I understand your point of view and we are also willing and eager to provide the necessary information to get this fixed. We appreciate all the effort you guys already put in this release.
We "feel" we are forced due to the "spl_autoload_unregister". It can also be that we just don't understand the design.
The warning is clear. We also have the preference of not uncommenting.
Current status of RC2: we have successfully implemented RC2 today!
So now the only gap is that we have uncommented that one line. For the rest the RC2 is great.

Now I am wondering how we can move further.
First of all: you say the autoloader is capable of working with other autoloaders by design.
In our autoloader, we set this:

"spl_autoload_register(array('Autoloader', 'doautoload'));"

When we use RC2, we see the function doautoload is never called. Maybe the naming of the class is interfering, we do not know. We do see that, after uncommenting, all is fine.

If this is not enough info, can you point me in the right direction on the information we need to gather?

Owner

Arul- commented Oct 3, 2012

@Teqa naming convention used for class files might help, is it PSR-0 Complaint?

If you could share your autoloader code that should help understand the problem better as well

Contributor

nickl- commented Oct 3, 2012

@Teqa the usual what you do, what you get, what you expect to get elaborations will help too.

If your autoload function never gets called and you never got any errors then I am left to believe that Autoloader was able to find and load the classes without a problem.

First of all i would like to thank you guys for the wonderfull job you did with Restler.

But i have to agree with @Teqa. I am trying to integrate Joomla framework inside restler but If i don't comment out the "spl_autoload_unregister" line then the Joomla autoloaders never get called.

Waiting for reply.

I would like to apologize for my bad english

Thank you

Contributor

nickl- commented Oct 16, 2012

English is fine =) thank you for your comments.

As mentioned previously it is early days and we are committed to making this work for everyone. Can you please elaborate on how exactly Restler is integrated with Joomla or anything else you think that may help to reproduce and solve the problems you are having. There are a few changes we're making to do better discovery etc and if joomla integration neeis something else we can add that too.

Can you shed more light on what their autoloader does, what class/file naming convention they employ etc?

Owner

Arul- commented Oct 16, 2012

@Arul- Yes this is the Joomla autoloader file.

@nickl- I will make a new git Repo that reproduce this error.

Contributor

nickl- commented Oct 22, 2012

@mathieu007 You don't have to make any huge efforts, just a short synopsis and links to the library should be sufficient to reproduce any problems. I would like to address this in combination with the other changes that I've incorporated if at all possible. Please let us know...

So how to I get you autoloader to load my project classes

Contributor

nickl- commented Dec 24, 2012

Autoloader essentially works with caching in mind, for this reason the cache will first be checked, before discovery starts, and updated before end.

Caching magic happens with the seen function (which is static) or AutoLoader::seen();

AutoLoader::seen($className); = check if class exist and return path to file if True
AutoLoader::seen($className, $classFilePath); = update className key with path to class
AutoLoader::seen($classMap); = Alternatively add a key = val collection with class name as key and path to php file as value, if this will simplify things for you.

So to recap, if at any point before the class is loaded by PHP (which means it is forwarded to Autoloader to discover) if you call AutoLoader::seen($className, $classFilePath); supplying the filename as it would be received by AutoLoader (or iow the exact class not found classname) and the path to the file (from anywhere on the php include path) Autoloader will simply map the requested class name to the filename you specified and load the filename.

There are several other ways to ultimately accomplish the same (create a new cache-able mapping), add a custom path to the include path you may use the convenience method AutoLoader::addPath('/some/path/to/add') which just saves you the trouble from doing the path separated concatenation with the current get_include_path and setting `set_include_path',

You will also be able to use prefixes which is a namespace prefix for a class name, as well as alias names where one class is then loaded using another name.

adding to the class map should be sufficient for most use cases, let me know.

django23 commented Jan 3, 2013

Because quite a lot of people are facing this problem, is it maybee an idea to add an option where you can enable/desable the spl_autoload_unregister function.

    public static function thereCanBeOnlyOne() {
        if (static::$perfectLoaders === spl_autoload_functions())
            return static::$instance;

    /*
        if (false !== $loaders = spl_autoload_functions())
            if (0 < $count = count($loaders))
                for ($i = 0, static::$rogueLoaders += $loaders;
                     $i < $count && false != ($loader = $loaders[$i]);
                     $i++)
                    if ($loader !== static::$perfectLoaders[0])
                        spl_autoload_unregister($loader);
        */
        return static::$instance;
    }

django23 commented Jan 3, 2013

Our could we maybee maintain a Branch where this function is absent.

Now I need to fork. And then I cant update easaly.

Owner

Arul- commented Jan 4, 2013

I can add a static var in Defaults to temporarily solve the issue, but permanent and performing solution will be what@nickl- is suggesting

Contributor

nickl- commented Jan 4, 2013

Guys I am currently working on this, just a little more patience please.

@django what would really help speed things along is if a few of all these many people who have this problem would take a moment to help us by providing me with examples of the classes that cannot be found and where they should be discovered.

If the problem is with a custom loader doing things other than loading of classes, without an example I cannot say if this could be resolved. One thing is for certain removing the unregister function is doctoring the symptoms and you are all avoiding the problem while introducing a whole legion of new ones, you just havent noticed it yet.

@arul please don't change the AutoLoader.php file if you don't mind, just for another couple of days, saving me from having to do some complex merge on top of it all.

Owner

Arul- commented Jan 4, 2013

@nickl- sure! I will wait :)

django23 commented Jan 4, 2013

@nickl- Thanks for your response.

I use it whithin a website that uses 2 differetn autoloaders. Those are not well writen, but can' t be changed on short matter.

I made a fork of your work already, and i' m trying to find a easy solution.

Keep you in touch.

Contributor

nickl- commented Jan 5, 2013

@django23 what exactly are the errors? Can you show me what the classes look like (iow what they are defined as) I only ned the line class SomethinOrAnother and the full path (relative to your include path) to the filename. If they are similar then one example should suffice.

It sounds like we are only do you a favour by cancelling out the badly written loaders =) is there anything besides loading the classes that you can see it doing perhaps? O you say two loaders, can you spot anything strange that THEY do. That's better =)

@ghost

ghost commented Jan 15, 2013

Not sure this is necessarily related but I think it might be...there seems to be a conflict in autoloader with log4php.

http://stackoverflow.com/questions/14348738/autoload-class-issue-with-restler-and-log4php

Contributor

nickl- commented Jan 16, 2013

@pagethis Awesome thank you for bringing it to my attention. At least this is something to test against, yeah \o/

@ghost

ghost commented Jan 16, 2013

@nickl- Let me know if there is anything I can do to help test for you. I am just digging into starting to use Restler but this kind of has me stuck on any progress. ;-)

Contributor

nickl- commented Jan 16, 2013

@pagethis What time zone you at? Welcome to github btw, but I was not able to get this info from your profile.

It's 6am here...you jabber/gtalk on nick at jigsoft dot co dot za if you want.

Owner

Arul- commented Feb 23, 2013

@nickl- read about this issue? http://stackoverflow.com/questions/15012683/restler-3-setup-configuration
I'm sure you have a fix for this

Contributor

nickl- commented Feb 23, 2013

Issue at SO is unrelated...

Owner

Arul- commented Feb 23, 2013

@nickl- we are suggesting 5.3 and above

where as stream_resolve_include_path requires 5.3.2

How do we go about for a solution for 5.3.0 users with out a fatal error like that?

Contributor

nickl- commented Feb 23, 2013

Also ReflectionMethod::setAccessible() was added in 5.3.2 but if you feel we need to spell out the obvious, I suggest we recommend to always use the latest version 5.3.x available but at minimum 5.3.9 which fixes a denial of service vulnerability through hash collisions and if using PHP-CGI you should not use anything less than 5.3.13 as several exploitable vulnerabilities were identified and fixed.

@Arul- I do not think we should encourage people to use anything less than 5.3.9 which makes any effort to avoid the said fatal errors obsolete. Agreed?

Contributor

nickl- commented Feb 26, 2013

Fatal errors are the bane of PHP and should not occur, agreed. Adding extra overhead for everyone else only because someone may still be using an outdated and dodgy release is also counter intuitive.

As compromise I will create a patch and submit it in separate issue. @Arul- Sufficient resolve?

Owner

Arul- commented Feb 27, 2013

@nickl- Yes! that will be better

Contributor

travisaustin commented Jun 5, 2013

nickl -

We have a custom autoloader which we use extensively, site-wide. We can't use Restler with our large library of custom classes because the Restler autoloader isn't correctly loading our classes.

Here's our autoloader:


// From http://www.php.net/manual/en/language.namespaces.php

namespace mspi;

class Loader
{
    // here we store the already-initialized namespaces
    private static $loadedNamespaces = array();

    static function loadClass($className) {
        // we assume the class AAA\BBB\CCC is placed in /AAA/BBB/CCC.class.php
        $className = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $className);

        // we get the namespace parts
        $namespaces = explode(DIRECTORY_SEPARATOR, $className);
        unset($namespaces[sizeof($namespaces)-1]); // the last item is the classname

        // now we loops over namespaces
        $current = "";
        foreach($namespaces as $namepart) {

            // we chain $namepart to parent namespace string
            $current .= '\\' . $namepart;

            // skip if the namespace is already initialized
            if (in_array($current, self::$loadedNamespaces)) continue;

            // wow, we got a namespace to load, so:
            $fnload = $current . DIRECTORY_SEPARATOR . "__init.php";
            if (file_exists($fnload)) require($fnload);

            // then we flag the namespace as already-loaded
            self::$loadedNamespaces[] = $current;
        }

        // we build the filename to require
        $load = dirname(__FILE__) . '/../' . $className . ".class.php";

        // check for file existence
        if (file_exists($load)) {
            require($load);
        }

        // return true if class is loaded
        return class_exists($className, false);
    }

    static function register() {
        spl_autoload_register("mspi\Loader::loadClass", true, true);
    }

    static function unregister() {
        spl_autoload_unregister("mspi\Loader::loadClass");
    }
}

Loader::register();

A class file would be located at mspi/NameSpace/ClassName.class.php. We would then use something like this to autoload that class:

$a = new \mspi\Core\Config('Test')

This would cause our autoloader to see if the file called mspi/Core/Config.class.php exists, and, if it does, it would require that file to load the class.

When we use Restler, it appears to be removing our declared auto loader from the queue.

Travis

Owner

Arul- commented Jun 7, 2013

Custom Autoloader Support

Restler 3.0 RC4 (currently only available in v3 branch) has support for custom autoloaders including composer's autoloader

Using our autoloader is the recommended way, we will continue to improve it. If you find it restrictive and not working for your use case please report it here so that we can figure out a solution

Meanwhile you should be able to use any autoloader

Contributor

travisaustin commented Jun 7, 2013

Do I need to do anything for my Autoloader to not be removed?

Owner

Arul- commented Jun 7, 2013

@travisaustin use your autoloader instead of Restler Autoloader, currently RC4 is using composers autoloader

See the restler.php file for an example

I am having a similar problem. I tried Restler 3.0 RC4 under the v3 branch, but I get the following error:

Warning: require_once(autoload.php): failed to open stream: No such file or directory
Fatal error: require_once(): Failed opening required 'autoload.php' (include_path='.:/opt/alt/php55/usr/share/pear:/opt/alt/php55/usr/share/php')

My original related problem was an error I received when trying to use Swift Mailer within Restler. More details here:
http://stackoverflow.com/questions/17396609/using-swiftmailer-inside-restler-class

Any help or insights would be greatly appreciated.

So I think I figured out I need to use "Composer" to generate the missing autoload.php file for the latest Restler 3.0 RC4 under the v3 branch, which I can't do on my shared host, so I'll revert back to the Restler 3.0 RC stable release on the Luracast website which works fine.

BUT, back to the issue at hand; how do I include the Swift Mailer library / class files? I've been trying everything I can think of, and I keep getting errors... :-(

Contributor

nickl- commented Jul 9, 2013

@travisaustin by simply commenting out the function call to spl_autoload_unregister you will effectively remove the "only one" functionality and yours should work however if it doesn't we have bigger fish to fry as it probably won't work with anp PSR autoloader then..

I have done work on a new loader that can take rule definitions which will do the looking up of custom naming conventions but unfortunately it is not quite ready for mass consumption. I am currently swamped in and worse of all doing rails so it will still take me some time before I can finish that. If you are interested in the work in progress current state I could create a branch and make it available. You will have to accept it as voetstoots and not expect support because we have our hands full already, as is.

Let me know but ETA probably closer to Monday still.

@nickL: If that comment regarding a branch was meant for me, then yes; I'll try anything.

Contributor

travisaustin commented Jul 9, 2013

@nickl- to be blunt, we don't want to have to teach another auto loader about our formatting. This would mean that we'd need to update 2 places if we ever modify our naming conventions.

Instead, I just want the autoloader to leave our existing autoloader registered and not assume that it's bad.

Contributor

nickl- commented Jul 9, 2013

@AndrewBucklin that is obviously not the Restler loader as it's not clever to use require_once and we are being very clever =)

a better solution if you can't control how many times per request a require is called is to wrap it in a if statement which verifies if it has been loaded or provided that something you're after already. It has to do with caching...

Have you looked to see if it is available on the include path you can add to the include path with the convenience method AutoLoader::addPath.

Contributor

nickl- commented Jul 9, 2013

@travisaustin instead of being blunt be sharp and realise I gave you the solution. Hint: see first sentence.

If you think your autoloader is bad then don't use it, no one else made that assumption. If you consider all the headaches you are having don't you think it's worth your sanity to simply conform to standards. Just think you won't need to change ever again and have no autoloaders to maintain. Sounds like win win.

Only trying to help dude!

Contributor

travisaustin commented Jul 9, 2013

@nickl- thanks for the reply, seriously. Sorry if I sounded rude -- I was trying to figure out how to be clear but not rude. I really appreciate your help.

I am not familiar with standards for auto loaders. Can you point me in the right direction? I am aware of the PHP docs for autoloaders (http://php.net/manual/en/language.oop5.autoload.php), but I don't know how to layout my classes and naming conventions so that I can use a "standard" auto loader.

Contributor

nickl- commented Jul 9, 2013

@AndrewBucklin I think you have other problems which won't be solved by the new loader. Where is that warning being raised, do you mind blowing that script up in a gist so I can have a look.

@travisaustin you can find the PSR-0 specification here on GitHub.

I gather the commenting out of spl_autoload_unregister in the Restler autoloader was tried and still found not to work.

Contributor

nickl- commented Jul 9, 2013

@travisaustin PSR-0 basically translates to

   /** replace \ with / and _ in CLASS NAME with / = PSR-0 in 1 line */
  include preg_replace("/\\\|_(?=\w+$)/", DIRECTORY_SEPARATOR, $className) . '.php';

@nickL: I appreciate you taking a look. I've still kinda new to this AutoLoader stuff. I've always used "require_once" for my external libraries and have never had issues. Any help / pointers would be greatly appreciated. Here's my code: https://gist.github.com/anonymous/e6b84e3ce6d4b9ca4bbf

When I do a POST to Restler, I get the following returned:
Fatal error: Class 'Swift_MailTransport' not found in /home/[snip]/public_html/[snip].php on line 63

Here's a link to the SwiftMailer library / code: https://github.com/swiftmailer/swiftmailer

Contributor

travisaustin commented Jul 9, 2013

@nickl- Commenting the auto loader does work, but I don't like having the edit the file every time we update. That sounds like I'm being lazy, but I'm just trying to do it the right way. It sounds like the PSR-0 is the way for me to go.

Contributor

nickl- commented Jul 9, 2013

@AndrewBucklin I cannot run php right now so I cannot look atn any libraries either.

You already identified the problem:

Warning: require_once(autoload.php): failed to open stream: No such file or directory
Fatal error: require_once(): Failed opening required 'autoload.php' (include_path='.:/opt/alt/php55/usr/share/pear:/opt/alt/php55/usr/share/php')

If I can see what is going on where that is happening then maybe I can tell you what you can do.

On the lack of caching:
You should use APC it is awesome! =) but require_once is not cacheable which is not so great.

@nickl- Actually the failed to open autoload.php only occurs when using the code from Github. If I use Restler 3.0 RC stable (linked from the Luracast website), I do indeed get past that error and get this error instead:

Fatal error: Class 'Swift_MailTransport' not found

Contributor

nickl- commented Jul 9, 2013

@travisaustin you can monkey patch spl_autoload_unregister for Luracast\Restler\AutoLoader in your code and avoid having to comment it out.

Somewhere before the autoloader gets loaded have something like this

<?php
namespace Luracast\Restler {
    function spl_autoload_unregister($loader) {
        return true;
    }
} 

And autoloader will use your Luracast\Restler\spl_autoload_unregister instead of \spl_autoload_unregister from core lib.

Contributor

nickl- commented Jul 9, 2013

@AndrewBucklin then I may be mistaken but I don't think using the Restler 3.0 RC is working for you as that class is not being loaded.

Based on PSR-0 that class will have to be on the include path somewhere in a folder Swift/MailTransport.php for a PSR-0 autoloader to find it.

As the problem is not at [snip].php it won't help to look there, the problem is that the class was not loaded before it got there. You can trie a require_once but there might be more to it than that which I cannot tell based on the information you've supplied.

If you manage to include the 'autoload.php' from the first error however the problem should be solved. If not comment out the call to spl_autoload_unregister in R3 autoloader and you'll be fine. Assuming that autoload.php is what Swift is using mind you.

Hope that helps! Got to run guys, good luck!

@nickl- Actually, the error regarding 'autoload.php' was Restler related. When using the v3 branch on Github, I get that error. I assume it's because I'm not using Composer. Just downloading the .zip and extracting it to my web server. Any idea where I can get that missing autoload.php Restler file?

I tried to use require_once('../../Swift/lib/swift_required.php') - as instructed by the SwiftMailer documentation, and I tried it in multiple places of Restler, but could never get Restler to actually include it I guess. I would always get the Fatal error: Class 'Swift_MailTransport' not found.

Contributor

nickl- commented Jul 9, 2013

@AndrewBucklin can you blow that file up on a gist for me please ./../Swift/lib/swift_required.php

I am not sure what autoload.php nor who is looking for it so I don't have enough info. You are including the vendor/restler.php right?

nickl- added a commit that referenced this issue Jul 13, 2013

Update AutoLoader.php
Remove method bypass loadLast resort.

As pointed out by @torel #150 and likely the fix for #72 and I am am sure we removed this before but somehow it came back.
Contributor

nickl- commented Jul 13, 2013

The fall back to other loaders functionality was disabled which should now be resolved.

nickl- added a commit that referenced this issue Jul 13, 2013

Update AutoLoader.php
Remove method bypass loadLast resort.

As pointed out by @torel #150 and likely the fix for #72 and I am am sure we removed this before but somehow it came back.

Reading this issue, It seems to be the same error I am getting when loading the AWS PHP SDK (aws.phar) when using Restler, all classes supposed to be loaded by using aws.phar cannot be found. I will try to comment out the spl_autoload_unregister.

http://stackoverflow.com/questions/17605125/aws-php-sdk-2-aws-phar-does-not-work-with-restler-framework

For me, commenting out the spl_auload_unregister does not work! It is impossible to get working aws.phar with Restler3 :(

nickl- added a commit that referenced this issue Jul 29, 2013

Update AutoLoader.php
Remove method bypass loadLast resort.

As pointed out by @torel #150 and likely the fix for #72 and I am am sure we removed this before but somehow it came back.
Owner

Arul- commented Aug 15, 2013

Restler 3 RC4 (just released) supports any autoloader that is PSR-0 compliant. That includes composer's autoloader

We will also be coming up with a brand new autoloader later that eliminates all the issues reported above

I will close this issue for now, but we can continue to discuss here

@Arul- Arul- closed this Aug 15, 2013

With RC4 I am getting "Internal Server Error: JsonFormat is not a valid Format Class." when using the Composer autoloader, the dev version doesnt work at all - am I missing something? I have run a "composer update".

require_once '../../../vendor/autoload.php';
use Luracast\Restler\Restler;
$r = new Restler();
$r->addAPIClass('Authors');
$r->handle();
Owner

Arul- commented Sep 13, 2013

It works for most of us, so we need to know about your configuration such as php version etc.

By dev version do you mean the v3 branch?

Hello,

I contacted Arul the last week-end about a problem to using Restler w/ Doctrine. Today I found this issue, and I try the tips of django23, comment the content of the thereCanBeOnlyOne() function... And it works fine! Above, you say this issue is supposed to be fixed in Restler 3RC4, but I use this version. I missed something in the configuration?

Thank you

Owner

Arul- commented Nov 26, 2013

Instead of using restler.php for autoloading, just use the autoload.php generated by composer and manage the dependencies using composer.json

You will be good to go!

Yes, I tried to include '../vendor/autoload.php' instead of '../vendor/luracast/restler/vendor/restler.php' but when I do this, routing fail:

{
    "error": {
        "code": 404,
        "message": "Not Found"
    },
    "debug": {
        "source": "Routes.php:383 at route stage",
        "stages": {
            "success": [
                "get"
            ],
            "failure": [
                "route",
                "negotiate",
                "message"
            ]
        }
    }
}

If I include restler.php and I comment the thereCanBeOnlyOne() function it works fine :/

Owner

Arul- commented Nov 26, 2013

That error is a good sign meaning that restler is fine and functional

When you use autoload directly you need to make sure your api class files mapped properly using composer.json

or you may use the include path as shown below

$loader = require_once '../vendor/autoload.php';
$loader->setUseIncludePath(true);

HTH

Contributor

nickl- commented Nov 27, 2013

-1 for require_once as it will stat which affects opcache-ability

instead of require_once you may do the same with something like

static $once = false;
if (!$once) {
  require 'something/only/once.php';
  $once = true;
}

or similar...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment