Is it possible to include code in a PHP class?

I want to create a PHP class, say Myclass.php. Now inside this class I want to define only the class itself and some instance variables. But all methods must come from the Myclass_methods.php file. Can I just include this file in the class body?

I have good reasons why I want to separate this. In short, I will have a backend in which I can change the business logic of the class, while everything else should remain untouched. The system supports all ORM and other things for me.

But if this is a bad idea, it would be better to regenerate the entire class file after editing the business logic (therefore, in this case, user methods will be defined).

Performance question: if Myclass.php is enabled only once during a single request, in fact Myclass_methods.php should also be enabled only once. Maybe wrong. Experts?

+46
oop php class
Dec 24 '09 at 10:19
source share
8 answers

No. You cannot include files in the body of a class.
In the file defining the class, you can include only those body files or outside the body of the class .

From your description, I want you to want this:

<?php // MyClass.php class MyClass { protected $_prop; include 'myclass-methods.php'; } <?php // myclass-methods.php public function myMethod() { $this->$_prop = 1; } 

Running this code will result in

 Parse error: syntax error, unexpected T_INCLUDE, expecting T_FUNCTION 

What is possible but it

 <?php // MyClass.php class MyClass { protected $_prop; public function __construct() // or any other method { include 'some-functions.php'; foo($b); // echoes 'a'; } } <?php // some-functions.php $b = 'a'; function foo($str) { echo $str; } 

By doing this, it imports the contents of the include file into the method scope, and not into the class scope. You can include functions and variables in the included file, but not methods. You could, but should not, paste all the scripts into it and change the way, for example,

 <?php // MyClass.php // ... public function __construct($someCondition) { // No No Code here include ($someCondition === 'whatever') ? 'whatever.php' : 'default.php'; } // ... <?php // whatever.php echo 'whatever'; <?php // default.php echo 'foo'; 

However, fixing the class in such a way as to exhibit different behavior is not how you should do it in OOP. This is simply wrong and you have to clean your eyes.

Since you want to dynamically change behavior, extending a class is also not a good option (see below for why). What you really want to do is write an interface and make your class using objects that implement this interface, so as to make sure that the appropriate methods are available. This is called the Strategy Pattern and works as follows:

 <?php // Meowing.php interface Meowing { public function meow(); } 

Now you have a contract according to which all imitation actions must obey, namely, have a meow method. Then define the meow behavior:

 <?php // RegularMeow.php class RegularMeow implements Meowing { public function meow() { return 'meow'; } } 

Now, to use it, use:

 <?php // Cat.php class Cat { protected $_meowing; public function setMeowing(Meowing $meowing) { $this->_meowing = $meowing; } public function meow() { $this->_meowing->meow() } } 

By adding a TypeHint to SetMeowing Meowing , you are convinced that the passed parameter implements the Meowing interface. Let it determine another behavior by the method:

 <?php // LolkatMeow.php class LolkatMeow implements Meowing { public function meow() { return 'lolz xD'; } } 

Now you can easily change the behavior as follows:

 <?php require_once 'Meowing.php'; require_once 'RegularMeow.php'; require_once 'LolkatMeow.php'; require_once 'Cat.php'; $cat = new Cat; $cat->setMeowing(new RegularMeow); echo $cat->meow; // outputs 'meow'; // now to change the behavior $cat->setMeowing(new LolkatMeow); echo $cat->meow; // outputs 'lolz xD'; 

Although you could also solve the above inheritance by specifying the BaseCat and meow abstract method and then deriving the specific RegularCat and Lolkat classes from it, you need to think about what you want to achieve. If your cats will never change the way they meow, continue to use inheritance, but if your RegularCat and Lolkat should be able to make arbitrary balls, use the strategy template.

For more design patterns in PHP, check out these resources:

+152
Dec 24 '09 at 10:46
source share

It is impossible to create a main class with the corresponding basic functionality, and then expand it using the necessary methods - this seems like a more logical approach.

+8
Dec 24 '09 at 10:24
source share

To begin with, it is not entirely clear why this problem is not solved in the best way using a base class containing methods, subclasses containing data, and dynamic loading of classes. I assume you have a good reason.

Once your provider supports PHP 5.4, you can do what you want using traits.

Code File:

 if ($pet === 'dog') include 'dog.php'; elseif ($pet === 'cat') include 'cat.php'; else die('Unknown pet'); class Pet { use PetSounds; } $myPet = new Pet(); $myPet->speak(); 

Cat.php file

 trait PetSounds { function speak() { echo 'meow'; } } 

Dog.php file

 trait PetSounds { function speak() { echo 'woof'; } } 

You can make it even cleaner by naming both include files the same, placing them in different subdirectories and using set_include_path () or defining the __autoload () function to choose between them. As I said, this same problem can be solved better using inheritance. If you have a problem with multiple inheritance, although, for example, you have four types of pets with five types of flowers with three types of hair, and you need a different combination of methods for each of 60 different classes, this is the right solution.

5.4 is currently only a release candidate (as of 2/24/2012) and even once released most hosts will not support it for many months - mine left 18 months after 5.3 release before they supported it . Until then, you should write completely separate and complete class files. However, you can format your classes with a possible change in values.

Right now, you can partially get what you want using magic methods and easily upgrade as long as they are available.

Code File:

 if ($pet === 'dog') include 'dog.php'; elseif ($pet === 'cat') include 'cat.php'; else die('Unknown pet'); class Pet { public function __call($name, array $arguments) { array_unshift($arguments, $this); return call_user_func_array("TraitFunc_$name", $arguments); } } $myPet = new Pet(); $myPet->speak(); 

Cat.php file

 function TraitFunc_speak(Pet $that) { echo 'meow'; } 

Dog.php file

 function TraitFunc_speak(Pet $that) { echo 'woof'; } 

However, you are limited in that your functions cannot access private and protected class properties and methods, and you cannot use this method to provide magic methods such as __get (). Traits will solve both of these limitations.

+6
Feb 24 '12 at 15:31
source share

How about using traits for this? Would this be an acceptable option? This is what I'm currently experimenting with and seems to work for quite some time.

A simplified version of what I'm doing is basically like this. I have an application with shared kernel files and several projects. As part of these projects, I have modules. I want to have features available for the whole project at a basic level, but only for this particular project.

My project controller

 if(is_file(PROJECT_PATH.'/project_extensions.trait.php')){ // additional functions for this specific project require_once(PROJECT_PATH.'/project_extensions.trait.php'); }else{ // no additional functions trait Extensions{}; } Class Project{ USE Extensions; // default functions shared between all projects function shared_stuff(){ } } 

Extension file

 trait Extensions{ // project-specific extensions function this_project_only(){ echo 'Project Only'; } } 

Module file in the project

 class MyModule extends Modules{ // modules extends projects in a different class not relevant here function do_something(){ echo $this->project_only(); } } 
+3
Sep 08 '14 at 9:37
source share

With PHP5.4, you can create dynamic objects as follows: https://github.com/ptrofimov/jslikeobject

But this is hardly the best practice.

0
Jan 09 '13 at 6:39
source share

The revival of the old question, but it is a fairly simple solution. Do you need common function calls to be exclusive to your class? If not, just specify your shared function file in the same scope as your class. You will need to create methods in your class, but they will only need to call a common function. Here is a simple example of a SOAP server:

 <?php include 'post_function.php'; $server = new SoapServer( null, array('uri' => "http://localhost/") ); $server->setClass( 'postsoapclass' ); $server->handle(); class postsoapclass { public function animalNoise( $animal ) { return get_animal_noise($animal); } } ?> 

post_function.php

 <?php function get_animal_noise($animal) { if(strtolower(trim($animal)) == 'pig') { return 'Oink'; } else { return 'This animal is mute'; } } ?> 
0
Sep 28 '15 at 18:59
source share

I had to do what you describe in cases where I support the free version and the premium version of the same software. Because, as @Gordon pointed out, you cannot do just that:

 class SomeClass { premium_file = "premium.php"; if (file_exists($premium_file)) { require($premium_file); } 

Instead, I do this:

  premium_file = "premium.php"; if (file_exists($premium_file)) { require($premium_file); } class SomeClass { ... 

For the functions you want to reference, create class methods in the main class and call the included file method by passing the $this pointer as a parameter. So that I can immediately understand where the functions are located, I will prefix the name of the included functions, as shown below:

  class SomeClass { ... // Premium functions public function showlist() { premium_showlist($this); } 
0
Jun 21 '17 at 16:14
source share

PERHAPS!

(using trait with php 5.4)

your_file.php

 include "additional_file.php"; class YourClass{ use additional_methods; public function My1() {} public function My2() {} } 

optional .php file:

 trait additional_methods{ public function My3() {} public function My4() {} } 



(thanks @user for the answer)

0
Dec 23 '17 at 9:55
source share



All Articles