Managing multiple classes from a single class in PHP - php

I'd like to apologise for the ambiguous title, it's the best one I could think of to define my problem.
I've got a single class in PHP that I want to be invoked from other scripts and I have a few libraries that I want to be able to call functions from, but I want to be able to call those functions from the other libraries via the single class I already have.
class Core
{
// code
}
I want to essentially do the following, Function->Core->Library Function.
The reasoning behind this is that I don't want to have a bunch of classes that get included when the file is run, causing the user to have to remember a bunch of different class names.
This is what I would essentially hope to achieve (but i'm pretty sure this is incorrect syntax)
$Core->Data->Get();

tadaam. That calls for Dependency Injection ;)
class Core
{
public $lib1;
public $lib2;
public function __construct(){
$this->lib1 = new Lib1Class();
$this->lib2 = new Lib2Class();
}
}

Related

PHP Access Class from Another class with Initializer

Ok, so I am building a web application relying on Zend PHP....
Before having to read everything to describe my nested functions, what I need is to be able to call a function from one class to another, which neither are extended upon another, are already extending a db constructor, which are all independently separate files called by one master initializing script .... (?) ... Thanks in advance, and there is a better example below as to what I mean.
My HTML Page calls a "master" include list which initializes and creates all the instances of all my classes so that all pages have common access to the functions. i.e. require('app_init.php');
Here is the most important excerpt of app_init.php:
require_once('class-general.php');
require_once('class-users.php');
require_once('class-identities.php');
$general = new General();
$users = new Users($db);
$iden = new Iden($db);
---class-general.php
$general is my basis for stupid common functions I use, as well as the DB constructor that all classes can be extended from.
----class-users.php
<?php
class Users extends General{
public function getUserID(){....random block of auth code.... return $randomID#; }
}?>
-----class-identities.php
<?php
class Iden extends General{
public function do_random_change_to_db($with_me){
....random prepared function using $with_me....
$this->logger->log("Someone with UserID: ". /*((?$this?) HERE:)*/ FIXME->getUserID() . " did something : ".$with_me ."." , Zend_Log::INFO);
$success="gucci";
return $success;
}
}?>
Right now, I am being tossed a PHP error for
Fatal error: Call to undefined method Iden::getUserID() in ...`
What would be the best way to go about this? I've tried to include one class file with the other one, but i dont exactly want to create a $FIXME= new Users(); either to save on memory space.
I also honestly would prefer to not extend any more classes off another at this time.
Thank you in advance.
If the getUserID method does not depend on any instance state (and it doesn't look like it does, though you haven't made it entirely clear), making it static will allow you to call it like so:
Users::getUserID();
If it does depend on instance state, you will need to call it on an instance of the Users class.
It seems to me that General's methods should actually be static as well, or perhaps even be free functions outside of a class. Remember: classes are used to encapsulate state. If there's no state that needs to be encapsulated, use class (static) methods or simple functions. Do not needlessly complicate your code by introducing objects and inheritance in which those paradigms don't make sense.

PHP Function Organization

I am writing a pretty basic php app and have created a pretty big mess of functions to do various things, e.g. display_user_nav(), display_user_list() etc. I want a way to organize these in a logical way. What I really need is something like a ruby module, but I haven't been able to find a php equivalent. I also feel that from a programming standpoint they don't belong in classes, as I already have a User object to contain information for one user, and don't want to have to create and store a new object whenever I want to use them.
What I am doing now:
display_user_table()
display_user_edit_form()
What I kind of want to be able to do (sort of like Ruby):
User_Functions::Display::Table()
User_Functions::Display::Edit_Form()
Any suggestions are appreciated.
If you are using PHP 5.3+, you have namespaces available.
So you can name your functions (the namespace separator is \):
User_Functions\Display\Table
User_Functions\Display\Edit_Form
However, it seems like using a class for this wouldn't be a bad idea. If you feel that display functions don't really belong to User (the same way many people think serialization methods don't make sense in the target objects), you can create a class like this:
class DisplayUser {
private $user;
function __construct(User $u) { $this->user = $u; }
function table() { /* ... */ }
function displayForm() { /* ... */ }
}
how about Abstract Classes!? or singletons? thats a good way to organize your code
Well you could break them out into helper classes for example:
$helper = new UserHelper();
$helper->renderTable($user);
$helper->renderForm($user, 'edit');
The architecture of the helpers could be more complexx and implement a fluid interface or something to that effect depending on how your classes operate.
Another approach might be to attach decorators to your objects to perform these functions.
There shouldn't be such functions at all but a template that takes care of all HTML output.
The problem is you are using functions in a wrong way: make a function only to repeat some operations more than once.
Do not use a function for just single operation.

Functions outside the class

I just want to tell you that I am newbie to OOP and it is quite hard to me, but here is my code:
class functions
{
function safe_query($string)
{
$string = mysql_escape_string(htmlspecialchars($string));
return $string;
}
}
class info
{
public $text;
function infos($value)
{
echo functions::safe_query($value);
}
}
Is there any way to make this sentence : echo functions::safe_query($value); prettier? I can use extends, than I could write echo $this->safe_query($value);, but is it a best way? Thank you.
edit: and maybe I even can to not use class functions and just make separate file of functions and include that?
Yes, just define your function outside of a class definition.
function safe_query($string){
return mysql_escape_string(htmlspecialchars($string));
}
Then call it like this
safe_query($string);
Using a functional class is perfectly fine, but it may not the best way to design your application.
For instance, you might have a generic 'string' or 'data' class with static methods like this (implementation missing, obviously):
class strfunc{
public static function truncate($string, $chars);
public static function find_prefix($array);
public static function strip_prefix($string);
public static function to_slug($string); #strtolower + preg_replace
etc.
}
The point of a class like this is to provide you with a collection of generic, algorithmic solutions that you will reuse in different parts of your application. Declaring methods like these as static obviates their functional nature, and means they aren't attached to any particular set of data.
On the other hand, some behaviors, like escaping data for a query, are more specific to a particular set of data. It would probably be more appropriate to write something like this, in that case:
class db_wrapper{
public function __construct($params); #connect to db
public function escape($string);
public function query($sql);
public function get_results();
}
In this case, you can see that all of the methods are related to a database object. You might later use this object as part of another object that needs to access the database.
The essence of OOP is to keep both the data and its relevant behavior (methods) in one place, called an object. Having behavior and data in the same place makes it easier to control data by making sure that the behavior attached to the data is the only behavior allowed to change it (this is called encapsulation).
Further, having the data and behavior in one place means that you can easily pass that object (data and behavior) around to different parts of your application, increasing code reuse. This takes the form of composition and inheritance.
If you're interested in a book, The Object-Oriented Thought Process makes for a decent read. Or you can check out the free Building Skills in Object-Oriented Design from SO's S.Lott. (Tip: PHP syntax is more similar to Java than Python.)
Functions outside a class litter the global namespace, and it's an open invitation to slide back to procedural programming. Since you're moving to the OOP mindset, functions::safe_query($value); is definitely prettier (and cleaner) than a function declared outside a class. refrain from using define() too. but having a functions class that's a mix of unrelated methods isn't the best approach either.
Is there any way to make this sentence
: echo functions::safe_query($value);
prettier?
Not really. IMO having a functions class serves no purpose, simply make it a global function (if it's not part of a more logical class, such as Database) so you can do safe_query($value); instead.
and maybe I even can to not use class
functions and just make separate file
of functions and include that?
Create files for logical blocks of code, not for what type of code it is. Don't create a file for "functions", create a file for "database related code".
Starting with OOP can be a real challenge. One of the things I did was looking at how things were done in the Zend Framework. Not only read the manual (http://www.framework.zend.com/manual/en/zend.filter.input.html, but also look at the source code. It will take some effort but it pays of.
Looking at the context of your question and the code example you posted, I would advice you to look at some basic patterns, including a simple form of MVC, and the principles they are based upon.

How to have a class spread across many source files?

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

Combining multiple classes gives me errors in PHP?

I'm creating a website with structure like this:
class main { }
class mysql extends main { }
class user extends main { }
class etc extends main { }
The idea is for these classes to use functions from each other. This doesn't work. How can I call a function from mysql in user?
EDIT:
All errors are similar to this one:
Fatal error: Call to undefined method user::function_in_mysql() in C:\foo.php on line 8
Martti Laine
The idea is for these classes to use functions from each other.
That's not what you're doing: Inheritance goes only one way. mysql, user, and etc inherit mains abilities but not those of each other.
You could have mysql extend user extend etc so that at least mysql can call all the functions but that probably won't make sense, as I think they are not ancestors but siblings to each other, fulfilling a distinctly different function.
You would have to either define any shared methods in main - often the best way to go - or introduce the classes to each other so they're able to call each other's functions. You could, for example, add an instance of each needed class as parameters to the constructor:
$etc = new etc();
$mysql = new mysql($etc);
// mysql's constructor sets $this->etc
// so that it can call etc's functions using $this->etc->function()
or, more complex, using the dependency injection or singleton patterns. I asked a related question some time ago about how to deal with this in PHP and got a lot of feedback, maybe it gives you some inspiration.
Having a class extend another makes the methods of the other (parent) available to it. So user extending main only makes the methods of main available to it. If other classes extend main it doesn't allow all of them to call each others methods. You could have user extend mysql and mysql's methods would then be available to user though I don't believe that fundamentally this is what you're looking for.
I think you're looking for something along the lines of dependency injection and not class inheritance.
For example if you wanted your user class to have access to your mysql class you pass it an instance of it in it's constructor.
class user {
protected $_mysql;
public function __construct(mysql $mysql) {
$this->_mysql = $mysql;
}
public function myMethod() {
$this->_mysql->myMysqlMethod();
}
}
$mysql = new mysql();
$user = new user($mysql);
$user->myMethod();
Here's some good reading on dependency injection.
PHP Dependency Injection
Symphony Dependency Injection
The Symphony link in particular is a pretty nice read on the overview of dependency injection and how to setup a dependency container.
That's not how extending a class works. All the functions that should exist in all classes should be part of main. Then functions that are specific to mysql go in that class. I'm guessing that the classes are not as closely linked in terms of inheritance as you think. If the user class needs to make calls through your mysql class, have a variable in the user class that holds a mysql object.
To call a function from mysql inside of user you could create an mysql object inside of user and call the function.
<?php
// this is user.php
$var = new mysql(); // <--if it takes parameters in the constructor
$var->method();
...
?>
For a better answer could you provide more information, as in, what errors are you getting?

Categories