I got hold of a dip into CI from CI forums and websites, which I have working. Basically; I have a fully working system in CodeIgniter, I have run tests that show a standard PHP file on the same server can access the classes and libraries that I made available.
One of the other legacy systems runs on Zend, and throws an exception when it incudes the CodeIgniter files. I can't get past:
$BM =& load_class('Benchmark', 'core');
in the dip file, with a long error being thrown by Zend. It throws (among much other information):
exception 'Zend_Exception' with message 'At least one error occurred including "Benchmark.php"; see includeErrors property'
Pretty much everything I can find on the internet finds ways to use the libraries from CodeIgniter, but that's the reverse of what I'm looking for. If I comment out the Benchmark loading, then it fails on Hooks, which leads me to believe that Zend has usurped or overloaded the load_class() function with its own, and is causing problems that way.
Has anybody gotten them working before?
I can't directly answer the question, but I just stumbled over a bit of rotting code referencing an Exception's "includeErrors" property.
After some search, I can maybe give a bit of context to what you observed.
Behaviour exists in some versions of ZF1 , see http://framework.zend.com/issues/browse/ZF-2463
if Zend_Loader includes a file
and the mere act of including it results in some PHP error (very often that will be E_STRICT if for example some inherited method signature doesnt match, or maybe if file is not found),
then it will throw an exception and add a "includeErrors" property to it
Related
I installed the last version (Oxygen) of Eclipse for PHP. But now there are lots of error annotations that I think they shouldn't be.
Almost all of them have to do with Exception:
throw new Exception('Exception message');
The annotation message in the popup hint is like so:
Exception cannot be resolved to a type
And the hint offers me some quick fixes, which are using the Exception class declared in libraries imported with Composer.
Why is that? As far as I know, Exception is still an internal PHP class (no need to import it). I know I should be using more specific Exception classes, but for now, Exception works for me. And it shouldn't be marked as an error in Eclipse. Prior versions didn't detect this as an error. Furthermore the application runs without any problem.
Is this a bug? Otherwise, how do I disable this type of error annotation?
EDIT:
Another annoying issue happening is that the code assistant is not displaying any php internal function. Only functions, classes and methods declared in my app or in imported libraries. For instance, if I type:
str
the code assistant displays classes from Doctrine, Geocoder, etc, and imported functions like "strip_quotes", but nothing about strstr, str_pad, strpos, etc
Did you forgot about namespaces and PSR-4?
throw new \Exception('Exception message');
So when you are using a class which must be autoloaded, you must declare it via use or call it with full path (with namespace).
If you don`t want to write correct code and this message is annoying you, then I'm pretty sure that you can turn off this message via Eclipse configuration.
The Problem
I'm working on a site which utilises two PHP frameworks running in parallel, Wordpress and CakePHP. Both of them contain a core function called __().
I know I can modify the core files of either framework to check if the function is declared and then not declare it:
if (!function_exists('__')) {
function __() {
// ...
}
}
However, the problem is that both frameworks need to be automatically updated from time to time, and when this happens, the core files get rewritten and the function comes back, causing fatal errors.
Wordpress is out of our control. Editors using the CMS want to be able to update the framework and plugins automatically from the Wordpress admin panel. This means I cannot really modify the Wordpress core to solve the problem, as they will just overwrite my changes every time they update.
CakePHP is updated by the developers, via Composer. Of course one basic solution would be to ensure that all developers know that when performing a Composer update, the core file declaring the function needs to be modified to fix the fatal error. This is still a pretty bad solution.
The Question
So although I am 99% sure there is no permanent solution to this, I'm wondering if any PHP gurus can think of a really clever, albeit slightly unconventional/messy, way of solving this with some code in the custom application within CakePHP. If there is something that can be done which I don't know about in PHP.
How the Application Works
The basic marketing pages of the site are pure Wordpress. CakePHP does not load on those pages.
On some sections of the site which require more complex functionality, CakePHP is loaded first. Before the page is rendered, CakePHP loads the Wordpress framework, then renders the page through Wordpress. These are the pages where both frameworks collide on the same function being declared twice.
My Thinking
When CakePHP is bootstrapped on a page, let it run up until the view is due to be rendered. At this point, only CakePHP has declared the function.
Check if the function exists before Wordpress gets loaded.
Somehow prevent Wordpress from redeclaring the function, ahead of time. We write this in our application code, which is fully controlled by the developers and committed to our Git repo.
I feel ridiculous posting this question, as I'm sure this is impossible, but if there is a really clever way of solving this, it would be so useful.
As ceejayoz said, fork CakePHP, and maintain your project on that fork.
Make a commit that will serve your project and that you can submit to the Cake team. As you suggest, make __ declaration conditional on it not already existing, declare it #deprecated in its phpdoc, and make a namespaced version that you'll convert everything to. Send that as a PR to Cake.
When you need to update your fork, merge the upstream branch into yours. You much watch the incoming Cake changes for use of the __ function and change them accordingly. Git will not catch these.
I have two codebases, one running as the primary web app, the other as the old code with legacy pages. Both codebases have their own composer installations, and that is where the problem occurs. When the first codebase has to call the second one, it is just a require secondApp. Both apps have, in requirements for other libraries, pake. The problem comes that Pake has a pake_autoloader function and the second one is noticing that the first already declared it, and throws an exception saying I cannot redeclare it. Both of these apps load Pake as a requirement for other libs. How do I get around the redeclaring issue?
Move both applications into one, and have only one composer.json file. Because by executing code of the "other" application, this really is only one big application.
A different idea would be to clearly seperate the two and only communicate via a defined interface, like making HTTP calls to the other application and using what's being returned.
A website built in Silverstripe 3.0 seems to be logging this error quite often:
"E_USER_WARNING: popCurrent called on ModelAsController controller, but it wasn't at the top of the stack"
The stack trace:
/framework/control/Controller.php (447)
/cms/code/controllers/ModelAsController.php (77)/framework/control/Director.php (296)
/framework/control/Director.php (119)/framework/main.php (126)
Does anyone have an idea what might be causing this?
Is that the full log statement you get? I've got quite a lot of similar statements (still 2.4 but that should be the same issue):
Warning at sapphire/core/control/Controller.php line 454:
popCurrent called on ModelAsController controller,
but it wasn't at the top of the stack
(http://www.foo.com/valid-page/piwik/libs/open-flash-chart/php-ofc-library/ofc_upload_image.php?name=wp.php)
So http://www.foo.com/valid-page really exists and some bot checks if you are running a vulnerable software (Piwik in this case). As long as you aren't using this software and are running the latest version, you should be find.
Most automated attacks I've seen target WordPress, Piwik, etc or some common extension (Timthumb); never something SilverStripe specific because it's not common enough to make it a good target of automated scans.
As mentioned by #micmania1 this issue was resolved by the framework maintainers a month after posting this question.
In web frameworks I've built and used in the past, there's been some means to specify some form of "last resort" error handler. I'd appreciate any help in determining how to accomplish that goal using CodeIgniter, which is a legacy part of a product I'm working on.
The goal of the last resort error handler is to capture any exception that's bubbled up, unhandled, from the application logic. Since, at this high framework level, the handler can't resolve the exception, a typical implementation is to log the error (with associated context) and present a user-friendly error page rather than a scary, technical exception page.
I wasn't able to find support in the CodeIgniter documentation, but I expect there must be support for this. Did I not find support because I should use PHP's set_error_handler() and set_exception_handler()? (I'm new to PHP, but expert in Java, Ruby/Rails.)
Thanks in advance for you guidance!
It seems CodeIgniter 2.0+ registers the handlers you specified to load the CI_Exceptions class. I usually put a MY_Exceptions library in the application/libraries folder to "catch" them before CodeIgniter. I'd rather handle them gracefully than let CI show it's error pages.