1

Following on from this other question.

In the PSR-1 Guidelines, the section 2.3 Side Effects rule restricts using include and declaring functions in the same file, e.g.:

<?php
// side effect: loads a file
include "file.php";

// declaration
function foo()
{
    // function body
}

But can you include a file inside a function?

e.g.

<?php
// declaration
function foo()
{
    // side effect: loads a file
    include "file.php";
}
Community
  • 1
  • 1
icc97
  • 11,395
  • 8
  • 76
  • 90
  • 2
    Yes you can, but than you can only use it in that method. – Vincent Beltman Sep 26 '14 at 12:15
  • 1
    According to the description, the rule is file based, not based on functions. -a file- should not have the side effect. So for my understanding, your second code sample should not be used. Coding OOP avoids this completely because you don't have any includes outside of the autoloader. – Daniel W. Sep 26 '14 at 12:15
  • Here's where my confusion comes in - the first comment says its ok, the second comment says its not – icc97 Sep 26 '14 at 12:19
  • @icc97 Simply seperate function declaration and includes. `include(config file);` second `include(function declarations file)`... – Daniel W. Sep 26 '14 at 12:26

3 Answers3

7

The thing to understand about this rule is the difference between declaration and execution. You may also think about it as loading of code vs. execution of code. When you load code, you do not expect it to do anything just yet. E.g.:

require_once 'utility_functions.php';

You include this file because you want to use some utility function which is in that file. You need to include this file to use any function in it, you can't not include the file. However, if that file goes off and produces some side effects, just by you including it, you've just gotten into a deep rabbit hole. For example, say the file always changed your error reporting settings. That would be majorly annoying. You'd always have to reset your error reporting every time you included this file:

require_once 'utility_functions.php';
error_reporting(E_ALL);
ini_set('error_display', false);

That's obviously madness and a source of potential problems.

On the other hand, once you execute code, you expect that code execution to do something, possibly even to have side effects. And you can control code execution, unlike whatever the file does simply by being included.

require_once 'utility_functions.php';

utility_do_something(); // side effects here are OK and/or expected
deceze
  • 510,633
  • 85
  • 743
  • 889
  • I was referring back to this answer and following on from your website, I just spotted your [Kunstube-Router](https://github.com/deceze/Kunststube-Router/) and more specifically the [RouteFactory.php](https://github.com/deceze/Kunststube-Router/blob/master/RouteFactory.php). That contains `require ...; class RouteFactory{...}` - I've done something similar quite a few times. But as far as I can tell that violates this side affects rule. Correct? – icc97 Oct 20 '14 at 19:23
  • 1
    Well, yes, that library is not really PSR compliant in that sense. I didn't want to dictate the use of an autoloader at the time, and I haven't come around to updating it yet. – deceze Oct 21 '14 at 04:10
  • Ok, great, at least I understand better what is / isn't compliant :) – icc97 Oct 21 '14 at 11:42
0

Yes, you may use include inside a function.

As far as this rule is concerned you can do anything you want as long as inside a function. Simply executing or including a file that declares a function doesn't run the code within the function. The function will only run if there is a call to it in some other file.

Include is mentioned in the rule just because it has the potential to cause side effects. This is no different to echo, sleep, or any other piece of code that has an observable effect when it runs.

bdsl
  • 288
  • 2
  • 9
0

As the warning seems to hint at, you need to split the functionality into 2 parts. Let's say you start with some file, MyFunctionality.php, that causes this warning, like:

<?php

namespace MyFunctionality;

require_once 'vendor/autoload.php';

class MyClass
{
    public static function someFunction()
    {
    }
}

Put the class in it's own file, MyClass.php:

<?php

namespace MyFunctionality;

class MyClass
{
    public static function someFunction()
    {
    }
}

And then load that from the original file:

<?php

namespace MyFunctionality;

require_once 'vendor/autoload.php';

require_once 'MyClass.php';
James John McGuire 'Jahmic'
  • 11,728
  • 11
  • 67
  • 78