3

Debugging someone else's PHP code, I'd like to selectively override one of their classes. The class is included via:

require_once('classname.php');

But, that appears in various places in the application. I'd rather 'simulate' the require_once, so that it never gets run at all. I.e. just define class classname as I want it. Then, the next time the file was require_once'ed, it'd be flagged as already-loaded and thus not reloaded.

I can create a classname.php file of my own, but I'd rather keep the testing I'm doing contained to a single file, as I'm doing this possibly for many classes, and I'd like easier control over the overriding.

In Perl, what I'd want to do would be:

$INC{'classname.pm'} = 1;

Is there a way to access PHP's equivalent of Perl's %INC?

Update: Consistently surprised by what PHP doesn't let you do...

My workaround was to use runkit's runkit_method_redefine. I load the classes I was trying to prevent loading, and then redefine all the methods I was trying to 'mock', e.g.:

require_once('classname.php');
runkit_method_redefine('classname','method','$params','return "testdata";');
benizi
  • 4,046
  • 5
  • 28
  • 25
  • 1
    If you want newclass.php included instead of classname.php, why not add two lines to the top of classname.php?: `require_once 'newclass.php'; return;` – Frank Farmer Jul 06 '10 at 17:54
  • Because I'm doing this for many classes, I don't want to alter the original class files. And because I want better control, I'd rather have a non-file-based solution. (i.e. I'll probably settle for adding a /tmp dir to include_path and creating only the class files I want overridden.) – benizi Jul 06 '10 at 18:58
  • Benizi dont worry I know what you mean, and its a top question. I couldnt find anything in PHP, its such a limited language. I stil have no clue how it became so popular when perl exists. I guess people are too lazy to learn. – ekerner Mar 30 '14 at 14:48

3 Answers3

2

Place:

<?php return; ?>

at the very top of classname.php file.

0

Then, the next time the file was require_once'ed, it'd be flagged as already-loaded and thus not reloaded.

require_once does this for you..

Additionally you could use something hacky like

if(!class_exists("my_class")) {
  class my_class {}  // define your class here
}
Gate
  • 44
  • 1
  • Sorry, was probably unclear in the explanation: the 'next time' is the first time. I want, in my own code without creating another file, to prevent `require_once('somefile.php');` from ever loading somefile.php. Your class_exists gets the gist of why I want to do this. – benizi Jul 06 '10 at 19:03
0

I'm thinking what you mean is that it's entirely possible that there is another "required_once" somewhere else in the code that would cause yours to be overwritten.

There are two things you can do:

1) Hunt down the first "required" and then comment it out.

2) Go into the class file and include your class and return before the other class is defined.

Daniel
  • 878
  • 6
  • 5