Why can't you have require* statements in a class definition?
Asked Answered
G

2

10

Possibly Related:
Why don't PHP attributes allow functions?

Pardon me if this has been asked before, but why can you not have something like the following:

class foo {

 require_once 'defines.php';

 private $_server = DB_SERVER;
 private $_username = DB_USERNAME;
 private $_password = DB_PASSWORD;
 private $_database = DB_NAME;
 public  $debug = false;
 public $_conn;

 function __construct() {                          
    $connection = @mysqli_connect($this->_server, $this->_username, $this->_password, $this->_database);
 }

 ...

}

Cheers,

EDIT: Looking to find out why this behaviour exists and why its not possible. How come the votes to close?

EDIT2 : Would also like to re-open this

Getty answered 5/5, 2011 at 16:26 Comment(24)
Related: Why don't PHP attributes allow functions?Correction
A blueprint sure, but that blueprint should be able to take static definitions from other sources to avoid repetition should it not?Getty
You can put it before the class.Bridewell
@Getty it could be argued that the require_once is a dependency (on the availability of the file, etc.) that doesn't belong in a blueprint. But I see what you mean - this would be handy to have sometimes.Correction
or you can simply put regular variables in the include file, and include the file within your constructor. you could even make the filename of the include file an argument for the constructor.Bridewell
@Bridewell thanks - that worked. Despite implementing a solution, I'm more looking to find *why this isnt the caseGetty
because that space is reserverved for defining class properties only. you can't simply put any code in that location. when would it run? on construct? then the code would go within construct. you can't do things like $blah = 1 + 2; in that space either because expressions are not allowed.Bridewell
I would argue I am defining - using elements from earlier definitions to compose the definition of the class..Getty
You would basically be able to get rid of the construct method and put a bunch of procedural code at the head of the class which could get ugly.Bridewell
@Bridewell but arguably, the interpreter could react to that with a syntax error then. I don't really understand why this decision was made either, seeing as require_* and include_* are language constructs and not functions.Correction
when looking at a class, you want to be able to cleanly see all of the properties it contains. this is a bad place for global defines anyways. how would coders know where to look for these global defines? in the head of a class is the last place I would look. Are these globals used by other classes? if so perhaps they should be placed in a higher level location.Bridewell
Related Bug report #1: bugs.php.net/bug.php?id=27569Correction
@Correction you will see that that bug was marked "not a bug". works as expected.Bridewell
Relate Bug report #2: bugs.php.net/bug.php?id=11835 money quote from Jan, a PHP internal: include is not allowed here :|Correction
My main point is, if it doesn't work, there are reaasons for it, and perhaps you are attacking the problem wrong. there is most likely an easier more intuitive way of handling the problem.Bridewell
I didn't mean for this to get closed as a dupe - I cast my vote too quickly, it really isn't one. Voting to reopen - although I doubt whether you will find a definitive answer.Correction
@Correction in your bug link i think tbiegacz put it best. why not just make a base class with these definitions and has all classes who need them extend that base class?Bridewell
@Bridewell It was what I suggested in my answer as well, but that doesn't feel like good OOP practice at all to me. Inheritances should be meaningful IMO, they shouldn't act as substitutes to include()Correction
The main thing is, you cannot do it. That will not change. As to why, there are probably many great reasons why, as a bunch were mentioned. As to my take, because the top of a class is meant for variable declarations. A require statement could not rightfully include variable declarations, and why would you want that? If you need a file / code to be included, do it in the constructor or a property of the class. You can argue about it all day, in the end it won't change, as I doubt many of the people here can speak for the PHP coders.Stewart
@Correction if they all need the same variable definitions, then they are most likely related in a menaingful way. OOP TEMPLATE pattern does basically this exact thing.Bridewell
@Bridewell fair enough, good point.Correction
@Pekka: Good link bugs.php.net/bug.php?id=11835 if you read the last comment it gives something that may be more of what the OP is looking for, not sure as no intent or example of defines.php was really given. @OP, You may want to look into extending the class and have a main class if you plan on using this a lot. I know you were not looking for solutions, but oh well :)Stewart
How is this a duplicate of "Why don't PHP attributes allow functions?"? require is not a function.Hardiness
I think that this is an interesting question, but ultimately subjective. It may be "not a real question".Hardiness
H
5

It was possible to require and include files both within function scope and at global scope, before Classes were added to PHP.

This is only a guess — I'm not sure what else we could do other than for the language designers to come and tell us their story — but I imagine it was believed that no benefit would be gained from adding this functionality to the "new scope" invented by the addition of Classes, especially considering the complexity added to the back-end in order to support it.

It's also not entirely clear what the scoping rules would be for any declarations made inside the required file.

In conclusion, I think you're asking the wrong question. Instead of "why isn't this supported?" it's more a case of "why should it be supported?".

I hope that this helps in some small way.

Hardiness answered 5/5, 2011 at 17:16 Comment(2)
The class scope is neither function, nor global scope. Its possible to use include-statements today, as it were before PHP implements classes. Nothing changed, except that a new concept arrived.Unroot
@KingCrunch: That's what I said. I have edited my answer in the hopes of making it more clear.Hardiness
U
2

It is because in the class definition "real" code is not allowed at all, only definitions for properties, methods and constants are allowed. You can put your include-statements into "main-scope" (procedural), functions and methods, like every other code.

class A {
  var $a = 1 + 1; // Parse error: unexpected '+'
}

However, as far as I know its not supported in any language. For example java uses static code blocks for this

class A {
  private static int a = 0;
  static {
    a = 1+1;
  }
}

In PHP just put your "static" code after the class itself.

class A {}
/* static */ {
  // do something
}

Its not possible to access private or protected static members this way.

Unroot answered 5/5, 2011 at 17:23 Comment(2)
Understandable. I guess at that point the definition of "real code" comes into contention. The argument is that defines and static constants should be eligible and don't contain any additional logic so to speak.Getty
Although a very loose analogy, C++'s #include (as a preprocessor directive) can go anywhere, including inside a class definition. I realise of course that some of the included file's contents may not be valid there.Hardiness

© 2022 - 2024 — McMap. All rights reserved.