I'm from a Java background, and I want to use an inner class in php. Every time I put the inner class though, I get a syntax error. Is this possible with PHP? Also, how do I reference the outer class? Do I get access to ALL its data members?
<?php
class OuterClass {
var $x = 15;
function __construct() {
}
class InnerClass { // error when InnerClass is static
function __construct() { // error when InnerClass is static
echo $x;
}
}
}
?>
This is used for a MoveClass (as in make a move) of a specific card game. I think it'd be good design to put these classes together because they don't make sense apart. Also, the MoveClass needs to know about some data members of the Game class. Why not make it a function? It's simply too big.
Edit:
What about nested classes? From what I understand, those have to be static? O_o
PHP does not allow for inner classes. Should you wish to access all of the data members from the parent class, I would suggest you employ Inheritance.
A possible alternative:
class OuterClass {
var $x = 15;
function __construct() {
}
}
class ChildClass extends OuterClass {
function __construct() {
parent::__construct();
}
}
You can envoke a method form the parent class by referring to the class itself; In PHP you can do this with the parent keyword. So, to refer to a method in the context of a class rather than an object we use :: as opposed to ->.
in PHP 5.4 or later, you can use PHP Traits which are designed more for multiple inheritance, but may suit your needs. From the PHP Documentation:
A Trait is similar to a class, but only intended to group
functionality in a fine-grained and consistent way. It is not possible
to instantiate a Trait on its own. It is an addition to traditional
inheritance and enables horizontal composition of behavior; that is,
the application of class members without requiring inheritance.
http://php.net/manual/en/language.oop5.traits.php
As mentioned in comments to this answer from another question, the PHP version of this functionality has been added in PHP 7. It does not seem to provide exactly what you are asking for. However, it should provide you a similar design pattern.
Here's the RFC describing how it works: https://wiki.php.net/rfc/anonymous_classes
As mentioned in the other answer's comments, search the RFC page for "nested" to see an example of nesting inside an outer class.
You might want to use a stdClass instead. Here's an SO question about it: What is stdClass in PHP?
You can't nest classes like that.
Look at the "extends" section of the manual.
Related
Simple question, is it possible to dynamically add traits to a php class in runtime without using eval?
As Glavic said, you can't without using eval() or reflection hacks (and I'm not even sure about that).
But it's very unlikely you really need to.
You can achieve a lot with dynamic class composition (composing a class with some functionality you want into another class). That's simply a matter of putting a reference to the class with the desired functionality into a variable in the hosting class.
class SomeClassWithNeededFunctionality {}
class SomeClassThatNeedsTheFunctionalityOfTheOtherClass {
private $serviceClass = NULL;
public function __construct (SomeClassWithNeededFunctionality $serviceClass) {
$this -> serviceClass = $serviceClass;
}
}
No.
p.s. you can have them in standalone files, and use include() ?
I am looking to tidy up some code I have inherited. Essentially we have two classes (A + B) that extend off two separate classes that do various things differently, however A and B also share some functions. At present the functions are copy and pasted between the two and obviously I know this is wrong. I am looking to see if there it a solution to this so that I only have to define the functions once so that both A and B can use these. Any help would be great!
From php 5.4 you could use Traits.
Here is example from manual
<?php
trait ezcReflectionReturnInfo {
function getReturnType() { /*1*/ }
function getReturnDescription() { /*2*/ }
}
class ezcReflectionMethod extends ReflectionMethod {
use ezcReflectionReturnInfo;
/* ... */
}
class ezcReflectionFunction extends ReflectionFunction {
use ezcReflectionReturnInfo;
/* ... */
}
?>
In an ideal world, it's possible that what you really want there is multiple inheritance, but that is not supported by PHP (or many other languages) as it is much more complex than single inheritance.
One alternative to consider is arranging your code so that both classes eventually inherit from some common ancestor, so that you can put your code here. This may not always be desirable or practical, however, particularly if some of the classes extended are from different libraries with no shared dependency.
You might be able to alter the ancestry of some of your classes by using "composition" and "delegation" rather than direct inheritance. The basic idea is that rather than class B extending class A, you store an instance of class A as a property of class B; when certain methods of class B are called, they call corresponding methods of the A instance, while other methods of B are completely separate, and can be inherited from somewhere else. The magic method __call can be useful for implementing this without having to know every possible delegated method in advance.
As of PHP 5.4, there is a form of "horizontal code reuse" called Traits. Traits are sometimes described as "compiler-assisted copy-and-paste", because they don't represent any OOP relationship between the classes where they are used, only a way of editing the functions in one place.
If the functions are public, you might want to declare the classes as implementing an Interface, which lets other code check that a set of methods are available, usually by using the instanceof operator. This can be used in combination with a Trait, which contains the details of how those methods are implemented.
I am currently working on a PHP project which includes extensive database usage. The basics are: I have a PDOFactory class which follows the Factory pattern and an abstract SQL class with static methods (just a container for those methods) which in turn talks to PDOFactory
As I said, the project involves extensive database usage, so the SQL class will contain numerous methods. However, they could be easily grouped, depending on what they deal with (i.e. session storage, user logging on/off, etc.). That would make the SQL class much easier to maintain and so on and forth. And here comes the big question: Can I have the source of the class contents spread across many files? There could be (at least) two possible solutions to this problem:
Multiple inheritance, i.e. having classes SQLSession, SQLUser, SQLblahblah and making the SQL class inherit all of them.
C++-like pre-processor* directives, i.e. #include SQLSession.php; or something like that.
I know there is no multiple inheritance in PHP, so that rules out option No. 1. Is option No. 2 even possible? Or does anybody know of better solutions to this problem?
*Or actually pre-pre-processor directives, since PHP is a pre-processor. :)
EDIT:
Here's an attempt to answer this question, based on Kalium's suggestion. It's a mess to read, but it works. However, I'm gonna stick with Bill's method as it's way cleaner.
class SQL {
private static $oInstance = false;
public static function getInstance()
{
if( self::$oInstance == false )
{
self::$oInstance = new self();
}
return self::$oInstance;
}
public $SESSION;
private function __construct()
{
$this->SESSION = new SESSION;
}
}
// this would be in another file
class SESSION {
public function printOne()
{
echo "One";
}
}
SQL::getInstance()->SESSION->printOne(); // outputs "One"
?>
I think you may be approaching this wrong. That's certainly not the best way to go about it. Try breaking the many functions into smaller utility classes and then using those to composite a larger class.
Don't use static methods, as it makes it hard to use something else than the SQL class
Use small classes, which have a single responsibility.
I think you should use the Builder pattern for your SQL instead of a motley container of static methods.
No, there is no multiple inheritance in PHP. Use delegation instead.
No, you can't include files to define methods of a class. You can only include files in contexts where code is executing, not in the middle of a class definition:
<?php
include("define-functions.php"); // OK
class Foo
{
include("define-methods.php"); // ERROR
function foo()
{
include("method-body.php"); // OK
}
}
PHP Parse error: syntax error, unexpected T_INCLUDE, expecting T_FUNCTION
in foo.php on line 7
Re your comment:
Since you're committed to using only static methods, why bother with a class at all? Just define functions in the global scope. Then you can include() as many as you want:
<?php
include("SQLSession.php");
include("SQLUser.php");
include("SQLblahblah.php");
SQLSession.php:
<?php
function SQLSessionStart()
{
...
}
function SQLSessionEnd()
{
...
}
You don't have access to static class member data with this solution, but you can just use global variables.
to me, it sounds like you're trying to create a monolithic chunk of code, which is the exact opposite of class based OO code - I'd recommend following the DAO blueprint of the Java core patterns, and implementing it in PHP for what you want to do :) that should cover all you're questions
I need some advise on my PHP code organisation.
I need classes where I can store different functions, and I need access to those classes in different parts of my project. Making an object of this classes each time is too sadly, so I've found a two ways have to solve it.
First is to use static methods, like
class car {
public static $wheels_count = 4;
public static function change_wheels_count($new_count) {
car::$wheels_count = $new_count;
} }
Second is to use singleton pattern:
class Example {
// Hold an instance of the class
private static $instance;
// The singleton method
public static function singleton()
{
if (!isset(self::$instance)) {
$c = __CLASS__;
self::$instance = new $c;
}
return self::$instance;
} }
But author of the article about singletons said, that if I have too much singletons in my code I should reconstruct it. But I need a lot of such classes.
Can anybody explain pros and cons of each way? Which is mostly used? Are there more beautiful ways?
See this excellent post:
Singleton Pattern vs Static Classes
More Resources:
How Bad Are Singletons?
Static DB class vs DB singleton object
When you say that you need to use a class of some sort to store functions, I am presuming that you'd normally be fine using plain functions but you do not want to pollute the global scope. This problem you will run into all the time in PHP.
If you are lucky to be working with PHP 5.3 you can use namespaces to pull the functions out of the global scope. Effectively, namespaces serve as a convenient way to auto-complete the prefixes you would normally have on functions to try and ensure their uniqueness. Because of this primitive implementation, there is no access control available for namespaces. If you wish to design an interface, you are out of luck, as all functions are globally accessible.
In this case, use a static class. No, it is certainly not the most beautiful solution but it is literally the best PHP can offer. With a static class you can effectively both prefix your functions for uniqueness and use access control.
Singletons are an object-oriented concept that solve a different problem. If your original design involves no objects, don't introduce them now.
That said, you have a function called change_wheels_count(). This function has a notion of state, and whenever you need state you need an object. I do not know if your code was just a quick example or your actual situation. If it was your actual situation, I would say you need neither a static class or a singleton.
I am wondering if php methods are ever defined outside of the class body as they are often done in C++. I realise this question is the same as Defining class methods in PHP . But I believe his original question had 'declare' instead of 'define' so all the answers seem a bit inappropriate.
Update:
Probably my idea of define and declare were flawed. But by define outside of the class body, i meant something equivalent to the C++
class CRectangle {
int x, y;
public:
void set_values (int,int);
int area () {return (x*y);}
};
void CRectangle::set_values (int a, int b) {
x = a;
y = b;
}
All the examples of php code have the the code inside the class body like a C++ inlined function. Even if there would be no functional difference between the two in PHP, its just a question of style.
Here is a terrible, ugly, hack that should never be used. But, you asked for it!
class Bar {
function __call($name, $args) {
call_user_func_array(sprintf('%s_%s', get_class($this), $name), array_merge(array($this), $args));
}
}
function Bar_foo($this) {
echo sprintf("Simulating %s::foo\n", get_class($this));
}
$bar = new Bar();
$bar->foo();
What have I done? Anyway, to add new methods, just prefix them with the name of the class and an underscore. The first argument to the function is a reference to $this.
I stumbled upon this question while looking for a way to separate declaration and implementation of class methods. Why? For the sake of code readability. When the declarations are in a separate file, or at the top of the class file, someone looking to use the class does not have to wade through the whole implementation to find out which methods are offered.
I did find something useful though: PHP interface classes. I don't think they are designed for it, but they serve the purpose: an interface class defines all the methods, and then the "real" class implements them. Here's an article about it:
http://www.davegardner.me.uk/blog/2010/11/21/why-you-should-always-use-php-interfaces/
Having the declaration of methods in header files separate from their implementation is, to my knowledge, pretty unique to C/C++. All other languages I know don't have it at all, or only in limited form (such as interfaces in Java and C#)
It's possible, but very, very hacky and not recommended. No reason to do it either.
First of all, in PHP, all class methods must be defined and implemented within the class structure (class x { }). It is in no way like C++ where you have the implementations (*.cpp) separate from the definitions (*.h).
Natively PHP doesn't support features like this, but since PHP5.4 you can dynamically add methods to object. As an example, you can look at this: https://github.com/ptrofimov/jslikeobject
No. You can consider 'declare' and 'define' to be interchangeable in that question.