13

from my understanding, require pastes code into the calling php file.

what if you were requiring from inside a method...it would paste the entire code/class inside the method, blocking the next statement in the method.

eg.

  function test() {

    require 'pathtosomeclasscode';
    somestatement; // any code after the require is blocked.

 }

how do i get around this, to be able to require code where-ever, without it being pasted in that exact spot?

hakre
  • 193,403
  • 52
  • 435
  • 836
Jeremy Gwa
  • 2,333
  • 7
  • 25
  • 31
  • Why would it block the next statement? – zneak May 02 '10 at 23:53
  • it will put all the code out of shape, eg. the class being pasted inside the function – Jeremy Gwa May 02 '10 at 23:55
  • 1
    @jera: That's not what happens. I've said this in my answer, but I'll reinforce it here: is there an error/malfunction you are experiencing that makes you believe this to be the case? If so, please provide us with more details so that we might rectify the source of the problem. – icio May 03 '10 at 00:51
  • icio is correct. This works fine (see my example code below). If you use require_once, and your included file just defines a class, then you're essentially lazy-loading the class definition, though in a somewhat messy way. – timdev May 03 '10 at 00:59
  • I was struggling at a related problem, but was googling wrong, so here is a link to the solution for someone who might have the same error: https://stackoverflow.com/questions/12242964/php-require-once-error-when-including-file-in-parent-folder – Emanuel Graf Oct 12 '20 at 13:14
  • Nesting classes is not allowed, right? – s3c Jan 20 '21 at 08:10

6 Answers6

22

Somewhat surprisingly, this appears to work just fine. The included code will execute inside the scope of Baz::bork() -- but the the code simply defines a class, and classes are global. So you end up with a defined class.

File: Foo.php:

<?PHP
class Foo{
      function bar(){
               echo "Hello from Foo::bar()!\n";
      }
}

File: Baz.php:

<?PHP
class Baz{

      function bork(){
               require_once "Foo.php";
               $f = new Foo();
           $f->bar();
      }
}

echo "testing internal definition:\n";
$b = new Baz();
$b->bork();

echo "\ntesting in global scope:\n";

$f = new Foo();
$f->bar();
echo "\nall done\n";

Output:

$ php Baz.php
testing internal definition:
Hello from Foo::bar()!

testing in global scope:
Hello from Foo::bar()!

all done

Now, I can't think of many places where you'd want to do things this way. People typically require_once() any possible dependencies at the top of their class file, outside of the class definition.

dns_nx
  • 3,651
  • 4
  • 37
  • 66
timdev
  • 61,857
  • 6
  • 82
  • 92
  • This can be useful when the required file is variable: `require_once $dirName . "/../{$fileName}.php";` – James P. Aug 15 '13 at 01:53
  • 1
    What if the file also specifies a namespace, will it handle that correctly? Yes, it did work. – SiXoS Mar 23 '14 at 13:08
  • @JamesPoulson This is also useful for conditional/delayed loading of code. Eg. a wordpress plugin might have code that is only used on frontend/backend/ajax call/specific page etc. Since plugins load before it is known which page/post you are on, you need to delay loading which in wp is done with actions, which will call yes, a function... This can speed things up server side, but also avoid loading unnecessary styles and scripts reducing needless requests... –  Dec 17 '14 at 09:00
7

Calling require, require_once, include or include_once will not stop the execution of code within your function unless there is a problem with the included script. The code within the included file is executed in the same scope as the function (with defined functions and classes being global), not inserted into it, replacing what else is there.

The other answers recommend using one of alternatives to require as a solution -- these solutions may work for you if the error in your scripts is to do with a conflict in naming (i.e. an attempt at redefining a class or function), otherwise you may wish to give us more details of what has occurred (or not occurred) to make you think that there is a problem so that we can help you solve the real cause.

On a further note, these file inclusion methods do not paste code into your script. Pasting is a tool that people use to maintain text. I suggest that you read the PHP manual to try and further your understanding of how these functions work:

Post again if you've got further questions on their working after looking into them.

icio
  • 3,060
  • 20
  • 22
1

try require_once? Just incase your including it elsewhere.

Titan
  • 5,567
  • 9
  • 55
  • 90
1

If you use include_once('script.php') you won't run into errors about classes being redeclared.

I haven't tried the following myself, but I'm thinking this setup might also work if you don't want to include_once() redundantly:

class Whatever {

    protected $classObject;
    public function __construct( /*...*/ ) {
        include('anotherClass.php');
        $this->classObject = new anotherClass();
    }

    public function someFunction( /*...*/ ) {
        $this->classObject->classObjectFunction();
    }

    public function anotherFunction( /*...*/ ) {
        $this->classObject->classObjectFunction();
    }
}

You could then call the following code which would each call a function in the same shared class object:

$Whatever = new Whatever();
$Whatever->someFunction();
$Whatever->anotherFunction();
buley
  • 28,032
  • 17
  • 85
  • 106
0

I think what you're saying is that you don't want the code to execute right away. If that is correcty, you have several options:

  1. You can move the require.

  2. You can also read the file using fopen(), then parse it. (You can't call eval because it won't understand the HTML, but you can do it with a parser)

waiwai933
  • 14,133
  • 21
  • 62
  • 86
0

As I see, you're using external files for loading classes, am I correct? Why don't you use Autoloading Classes. I know it won't work when you want to load different class bodies in different circumstances, but I really don't know if it's a good practice.