6

I have a large chunk of legacy php code that I need to interface with that looks like this:

//legacy.php

function foo() {
}

function bar() {
}

I want to be able to wrap these legacy functions in a class or somehow require_once without polluting that global namespace or altering the original file.

hakre
  • 193,403
  • 52
  • 435
  • 836
james
  • 3,543
  • 8
  • 31
  • 39
  • 1
    I would suggest that this is a good moment to consider refactoring. If it's really old code as you're implying, I'd say there's a high likelyhood of that code containing some nasty stuff in there. You'll need to clean it up at some point; now would seem like the perfect opportunity. – Spudley May 19 '11 at 15:29
  • I gave an answer. It's likely it doesn't say anything you don't already know. There's no reasonable way to do this without modifying the file in some way AFAIK. – Matthew May 19 '11 at 15:33
  • @konforce have already given you the solution, if you would like us to suggest on a more feasible solution posting of some of your sample code could help us. – Ibrahim Azhar Armar May 19 '11 at 15:38

2 Answers2

2

You can use a namespace or static methods in a class:

// original file: foo.php
class Foo
{
  public static function foo() { }
  public static function bar() { }
}

// new file:
require 'foo.php';

class MyNewClass
{
  public function myfunc()
  {
    Foo::foo();
  }
}

$x = new MyNewClass();
$x->myfunc();

Both would require slight modifications to the file. e.g., Calls to bar() would have to be changed to Foo::bar() with the above example (class with static methods).

OR, using a namespace:

namespace foo;

use \Exception;
// any other global classes

function foo() { }
function bar() { }

In your file:

require 'foo.php';

foo\foo();
foo\bar();
Matthew
  • 47,584
  • 11
  • 86
  • 98
  • 1
    Note that using a namespace is likely to require less work... If the code uses no classes, then perhaps all you need is a `namespace foo;` at the top. – Matthew May 19 '11 at 15:34
  • I guess I don't understand your solution. I need to call the original foo() or bar() function from inside the class. – james May 19 '11 at 15:46
  • 1
    @james, the above is modifications to the original file. Considering those functions were written without knowledge of your new code, there's no need to merge them with your own class files. In any code you write, you would simply call the functions as `Foo::bar()`. Spudley's answer is actually simpler to implement, but it suffers from the same problem as this one: if `foo()` calls `bar()`, then you'll need to modify the original file. I'd recommend using a namespace... it's probably the simplest solution. – Matthew May 19 '11 at 15:51
1

As mentioned in the comments, I'd seriously recommend seeing this as an opportunity for a refactoring excersise.

But assuming you can't do that for whatever reason, the answer to your question depends on whether the functions within the original legacy.php file call each other internally.

If not, then yes, it's fairly trivial to do something like this:

<?php
class legacyFunctions {
require_once('legacy.php');
}
?>

But note that this will just set them up as public functions within the class, rather than static, so in order to call them, you would have to instantiate an instance of the class first, possibly early on in your code as a global (it would be a classic example of a singleton class).

If you're using PHP5.3, you might want to consider using a PHP namespace rather than a class for this, which would resolve the issue of having to instantiate the class. The mechanism would be much the same though.

However, if your functions call each other within the legacy php code, then none of this will be possible without at least some edits to your legacy code to change the function calls to their new versions.

Spudley
  • 166,037
  • 39
  • 233
  • 307
  • so doing the require will wrap all those loose functions as class methods? – james May 19 '11 at 15:47
  • 1
    Functions calling each other is not a problem with namespaces. However, referencing classes (e.g., Exception) would stop working. (Although if this code is old, perhaps it doesn't reference any classes.) – Matthew May 19 '11 at 15:48
  • also i am using php 5.3 and the namespace solution solves half of my problem (naming conflicts) – james May 19 '11 at 15:48
  • @conforce this legacy code calls other objects so the potential for things like Exception, and other classes not being reference correctly is a real concern – james May 19 '11 at 15:49
  • 1
    It will indeed. The syntax won't be great, but it will default to making them public methods of the class, so it will work. However, as I said, if they call each other (and you've implied this is the case in a comment on the other answer), those function calls won't work any more; that's the real problem you face. Also, if there's any loose code in the file (ie outside of any functions), that will give syntax errors if you include it into a class. – Spudley May 19 '11 at 15:52
  • 1
    given everything you've said, I don't think you're going to be able to avoid making code changes -- just bite the bullet and do it. :) – Spudley May 19 '11 at 15:53