CodeIgniter problems after upgrading to PHP 7.3 - php

I have upgraded my PHP to version 7.3.4 for my CodeIgniter 3.1.10 installation. After this I noticed that some parts of my website are not working anymore as before (with PHP 5.6) they did.
One of the use cases is when I type in a faulty URL like so:
www.abc.com/nl-be/antwerpen/this-is-a-bad-url
Normally this would go to my 404 page , but right now I first got the following error:
Message: Call to a member function helper() on null
Filename: D:\wamp\www\codeigniter\application\hooks\LanguageLoader.php
The code is:
class LanguageLoader
{
function initialize() {
$ci =& get_instance();
$ci->load->helper('language');
$site_lang = $ci->session->userdata('site_lang');
if ($site_lang) {
$ci->lang->load('message',$ci->session->userdata('site_lang'));
} else {
$ci->lang->load('message',$ci->session->userdata('site_lang'));
}
}
}
I managed to find a work-around to get past this problem using the code below (Is this correct?):
class LanguageLoader
{
function initialize() {
$CI =& get_instance();
if ($CI === null) {
new CI_Controller();
$CI =& get_instance();
}
$CI->load->helper('language');
$site_lang = $CI->session->userdata('site_lang');
if ($site_lang) {
$CI->lang->load('message',$CI->session->userdata('site_lang'));
} else {
$CI->lang->load('message',$CI->session->userdata('site_lang'));
}
}
}
After checking the value of $CI, this time it would not be null, but would be filled in.
At this point after going to the same faulty URL, i am getting the following error message:
Message: call_user_func_array() expects parameter 1 to be a valid callback, class 'Error' does not have a method 'my404'
Filename: core/CodeIgniter.php
The code in CodeIgniter.php at that line contains:
call_user_func_array(array(&$CI, $method), $params);
The error is especially weird, since i have a my404 method in my Error class:
class Error extends My_Controller {
public function my404() {
//Code to show my 404 template
}
}
EDIT: my URL's look like www.<sitename>.com/<languagesegment>/<optionalcityname>/<pathcontroller&function>
If the optionalcityname is filled in in the URL, the entire website is branded in the cities colors and logo etc. If it is left out, the "normal" site appears.
When going to the "normal" site, my 404 page gets shown correctly.

I've never used CodeIgniter but a quick look at the documentation seems to suggest that, inexplicably, they don't use namespaces. This is pretty unheard of for a modern codebase, and you're learning why.
PHP 7.0 introduced the Error class as the base class for all internal PHP errors. Since your code is not namespaced, you're trying to overwrite this built-in class. If you looked at your error log you'd see something like this:
PHP Fatal error: Cannot declare class Error, because the name is already in use in...
Rename your Error class to something that isn't a reserved name and it should get you past this problem.

Related

CodeIgniter extend CI_URI undefined method

So I've been in the process of updating someones old CI 1 to CI 3 code. In process. In particular, the URI class extension is not working. I've read the CI documentation switched to __construct() and moved it to the application/core directory. I've checked SO and all cases are correct, but I still get the following error:
Call to undefined method MY_URI::last()
My code below
class MY_URI extends CI_URI {
function __construct()
{
parent::__construct();
}
function last()
{
return $this->segment(count($this->segments));
}
}
Thoughts as to why this may be happening with the switch? Checking StackOverflow it said chek your config settings by the config has the correct
$config['subclass_prefix'] = 'MY_';
I'm calling it with:
$lastURI = $this->uri->last();
Update: I've also tried the
exit('MY_URI.php loaded');
trick at the top which seems to work, but it still throws the error when I remark it out and never loads the extension.
Place your MY_URI.php file inside the application/core/MY_URI.php & update the function like following.
public function last(){
return $this->segment($this->total_segments());
}
call it like below
$last = $this->uri->last();

Is autoloading classes from an autoloaded class function allowed in PHP?

I am using Drupal 7 and I am using my custom module's .info file along with the "files[] = ...." directive to allow autoloading of my classes when required. Each class only contains static public functions and everything is working nicely when these functions are called from a function of the general scope.
Working example:
If I go to /devel/php and call the function ClassTwo::getValue() everything is executed without error.
Example with error:
If I call the function ClassTwo::getValue() from within another autoloaded function ClassOne::generate() an exception is thrown that the class ClassTwo() doesn't exist. The error is solved if I specifically include the file containing the class ClassTwo.
I don't believe it has something to do with Drupal's autoloading mechanism though. Is my scenario allowed in PHP 5.3?
For better clarification I have added below example code. That's the nearest I can provide to working code.
mymodule/mymodule.info
name = "MyModule"
core = "7.x"
files[] = "includes/plugins/ClassOne.inc"
files[] = "includes/plugins/ClassTwo.inc"
mymodule/mymodule.module
function mymodule_page_callback() {
return ClassOne::generate();
}
mymodule/includes/plugins/ClassOne.inc
Class ClassOne {
static public function generate() {
$value = ClassTwo::getValue();
// Process $value
return $value;
}
}
mymodule/includes/plugins/ClassTwo.inc
Class ClassTwo {
static public function getValue() {
// Somehow retrieve the value.
return $value;
}
}
UPDATE: Using Drupal's xautoload module with PSR-4 everything works incredibly fine and I have turned to this method as a solution. If anyone has an answer though, other than PSR-0/PSR-4, I would like to know it.

ZF2 - Call to a member function on a non-object error

I am trying to implement a simple roll-a-dice service and use it in a .phtml file. I know my issue has been reported often on SO, but I could not find a solution in other questions.
I get the following error message:
Fatal error: Call to a member function getDiceResult()
on a non-object in rolladice.phtml on line 11
Here is line 11:
<?php
$result = $this->rollADiceService->getDiceResult();
echo "<p>Roll-a-dice result: ".$result."</p>";
?>
The controller is set-up as following:
class RollADiceController extends AbstractActionController
{
private $rollADiceService;
public function setPluginManager(PluginManager $plugins) {
parent::setPluginManager($plugins);
$this->rollADiceService = $this->getServiceLocator()
->get('RollADiceService');
}
...
In Module.php, I have:
public function getServiceConfig()
{
return array(
'factories'=>array(
'LoginLogoutService' => function() {
return new LoginLogoutService();
},
'RollADiceService' => function() {
return new RollADiceService();
},
),
);
}
I am using the same technique (i.e., setPluginManager) to retrieve instances of my services in other controllers without issues. What am I doing wrong?
P.S.: Using a debugger, I can see that setPluginManager() is called, but that the $this->rollADiceService variable is initialized with null. Why?
Ultimately, there were two issues:
i) I refactored my code to pass the result of the call to rollADiceService->getDiceResult() as a variable which $this can access.
ii) Hijacking setPluginManager() is not a recommended practice. I've implemented factories for my controllers depending on services.
your problem is realy simple I think.
<?php
$result = $this->rollADiceService()->getDiceResult();
echo "<p>Roll-a-dice result: ".$result."</p>";
?>
Add these brackets after rollADiceService should fix your problem. Without brackets, Zend View instance try to access to view variable named rollADiceService, which is obviously NULL.
By adding brackets, you tell to View it should look for rollADiceService in registered view helpers.
I hope it helps :)

Call to undefined method. Can't figure out why

I have set up a class with a few functions in it. I've included a seperate php file into the main one. I have a few public functions set up, all which are working. I just went to add a new one, and its throwing an error and I can't figure out why.
if(!class_exists("classBase"))
{
class classBase
{
public function printName()
{
$name = 'Test Name!';
return $name;
}
}
}
I'n my separate file that is included into this one, I am trying to call this function as I am all my other functions in the file.
<?php $this->printName(); ?>
I tried declaring the function before and after the file is included, But for whatever reason, this is throwing the error:
Fatal error: Call to undefined method classBase::printName()
I even tried copying a working function, appending a number to the function name, and calling that new function. But still throwing an error. I'm confused as to why its not working.
You need to initialize an instance of that class. In your example:
if(!class_exists("classBase"))
{
class classBase
{
public function printName()
{
$name = 'Test Name!';
return $name;
}
}
}
$myInstance = new classBase();
$myInstance->printName();
Face Palm
So damn embarassing...
I have two localhost test sites set up. I was editing the class file on the site I wasn't testing, and adding the call to the function into the site I was testing. Therefore it was throwing the error and it was correct, the method was never defined.
Just spent 45 minutes wondering what I was doing wrong...
Clearly I need to step away from the computer and go on lunch.

PHP Method Disappears?

I am including one PHP script into another using PHP's require_once() method. This script contains a class, TemplateAdmin, which instantiates itself right after the script, like this:
class TemplateAdmin {
// Class body...
}
$templateAdmin = new TemplateAdmin();
This was working fine for a while. However, I have adopted a new importing technique to include classes and packages. I have tested this new technique, and it works! However, for some strange reason, none of the methods in any of the classes I import are there when I need them. However, it seems as though the instance variables are still there.
For example, when a class with this absolute path is called:
require_once("C:\wamp\www\wave_audio\system\server\templates\TemplateAdmin.php");
... I get this error in the call stack:
Fatal error: Call to undefined method stdClass::top() in C:\wamp\www\wave_audio\cms\index.php on line 189
This error is referring to my use of the top() method inside of the TemplateAdmin class.
Does any one have any idea as to why this is happening??? If this helps, I have been using require_once() all along, I am running PHP 5.3.5 on a Windows XP Media Center machine.
Thank you for your time!
Assuming you dont want to use globals here is one way that only requires a few changes.
TemplateAdmin.php:
class TemplateAdmin {
// Class body...
}
return new TemplateAdmin();
Return include once in import:
function import($classes) {
//Convert ECMAScript style directory structures to Unix style
$address = str_replace(".", "/", $classes);
$address = INSTALL_ROOT . "system/server/" . $address . ".php";
if (file_exists($address) && is_file($address)) {
return require_once($address);
} else {
die(""" . $classes . "" does not link to an existing class");
}
}
Assign the variable:
$adminTemplate = import('templates.TemplateAdmin');
I have a feeling your php error message is accurate. I know on your stripped down version, you pieced it together how you're sure it's setup but it's obviously not a direct copy/paste since it's like:
class TemplateAdmin {
public function top() {
//The "top" method...
}
}
So, the error message says that the method "top" is not defined. If it were not including your file properly, it would tell you that the class you instantiated doesn't exist. Either that method does not exist in the class you think it is, or the method has been unset somewhere in that object instance. Trust your error message.

Categories