TalkPHP
 
 
Account Login
Latest Articles
» The basic usage of PHPTAL, a XML/XHTML template library for PHP
» Vulnerable methods and the areas they are commonly trusted in.
» Simple way to protect a form from bot
» The Basics On: How Session Stealing Works
» How to keep your forms from double posting data
IRC Channel
IRC Speech Bubble Join the friendly bunch on IRC...
(#TalkPHP on Freenode)

...Also available via a web interface.

See this thread for information on the TalkPHP Free Hugs Initiative™. Subject to availability.
Associates
Associates
CSS Tutorials
Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old 04-29-2008, 02:39 PM   #1 (permalink)
The Contributor
 
Evulness's Avatar
 
Join Date: Apr 2008
Location: Tampa, FL
Posts: 65
Thanks: 6
Evulness is on a distinguished road
Default New approach

over the weekend, i decided to retry my CMS from scratch. Not only because it wasn't organized, but because the code was ugly.

i wanted alittle bit more organization in my classes...

Well, heres my problem...
i have db.class, session.class as my 2 base classes.
the way i'm planning, everything else will be extended from these.

right now I've got the database class down to basics. connect(), query(), fetch(), get_one(). and my session class is simple, start() set, unset, destroy, show, verify.

now, i am in NO way, adept at oop, i'm still learning. took me all weekend to write these 2 from scratch. before i used tuts and shit as a guide. which was good, becausw what i wrote worked, surprisingly, but after looking it over, i thought of things to make it better.... and tada, we have my 2 new classes...
Evuldb.class
EvulSession.class

question i have is... how can i use both classes in a new class? if i can't extend more than 1?

aka, as an example:
how they extended their user.php from mysql.php
TechTuts - Learn. Share. Create.

yet, how can i extend 1 "user.class" from BOTH db.class and session.class in this mannor?

or rather is there a way i can use these classes in a new one? like maybe extend one, and include the other?
if i read right, and understand classes and oop right... then i can't do it in a class, i would have to do regular functions and expressions, etc...
right?
__________________
"Knowledge is power. Abuse it."~Evulness
My portfolio: www.evularts.com
Send a message via AIM to Evulness
Evulness is offline  
Reply With Quote
Old 04-29-2008, 02:54 PM   #2 (permalink)
The Contributor
 
Evulness's Avatar
 
Join Date: Apr 2008
Location: Tampa, FL
Posts: 65
Thanks: 6
Evulness is on a distinguished road
Default

ooo ooo ooo
nevermind...
PHP: The Basics - Manual
__________________
"Knowledge is power. Abuse it."~Evulness
My portfolio: www.evularts.com
Send a message via AIM to Evulness
Evulness is offline  
Reply With Quote
Old 05-05-2008, 04:47 PM   #3 (permalink)
The Contributor
 
Evulness's Avatar
 
Join Date: Apr 2008
Location: Tampa, FL
Posts: 65
Thanks: 6
Evulness is on a distinguished road
Default

hmm, heres a question for you, because i can't seem to get the results i want...
how would i do the following...

-mysql.class
--user.class extends mysql.class
-session.class

how can i make my session.class work inside my user.class?
or to put it another way. How can i use my session.class objects in objects inside my user.class, if i can only extend once.

like i have my user.class set to do login stuff, but when that login function is used, i want to be able to use my session.class at the same time and set the sessions that way..... can i do this how i want? or should i not use a class in this mannor, just include, and use both classes in a "Login" script through normal means.
because at the moment, the latter sounds easier.

with my session class, i can:
Code:
include_once ('evulsess.php');
$session = new EvulSession();

$session->set_var($key, $value); //same as $_SESSION['$key']=$value;
$session->get_var($key);//returns $value
$session->unset_var($key);
$session->DestroySession('Hacking attempt!');
$session->show(); //returns $key : $Value of ALL session variables for debugging
and 
$session->validate();
//checks if usr_name is set, if it is, then it checks IP, then checks user agent, then
//checks time. if any are false, script die()'s, else if no errors returns $session->set_var('Is_Valid', true);
its a nice class, but... i wanna be able to $session->set_var(); inside my already extended user.class

any ideas?
would i need to use call_user_func(), or call_user_func_array() ? if so how would i do this?

__________________
"Knowledge is power. Abuse it."~Evulness
My portfolio: www.evularts.com
Send a message via AIM to Evulness
Evulness is offline  
Reply With Quote
Old 05-05-2008, 06:53 PM   #4 (permalink)
The Acquainted
 
drewbee's Avatar
 
Join Date: May 2008
Posts: 175
Thanks: 9
drewbee is on a distinguished road
Default

Heres how I do it:

Page.class -- handles database connections, user authentication, session management, and provides the layout for children classes to actually draw the pages. (Inherit forms.class parent class and then children form specific classes (register, login, profile etc)

While I don't have it seperated in classes, I personally never needed or seen a need for it. Every single page will require at the very least the ability to draw the page. So when im initiating my object, I pass to it certain values.

ie
$requireLogin = If user is not logged in, throw an error message
$requireLoggedOut = User must be logged out to access the page
$dbConnection = will determine if the page needs a database connection.
For me personally, I use databases to store session information / tracking so that value is obviously always set to true. But that is just my case.
PHP Code:
$page = new Page(truefalsetrue);
 
class 
Page
{
   function 
Page($requireLogin$requireLoggedOut$dbConnection)
   {
        
// Do stuff
    
}
 

Send a message via AIM to drewbee
drewbee is offline  
Reply With Quote
Old 05-05-2008, 08:15 PM   #5 (permalink)
is cute and cuddly
 
delayedinsanity's Avatar
 
Join Date: Mar 2008
Location: Vegas, Baby
Posts: 963
Thanks: 31
delayedinsanity is on a distinguished road
Default

You may want to look into design patterns. In particular, the singleton, though that may not be the one you decide to go with. It just happens to be the first one I learned about and have been using with a lot of success lately in my project. Basically it allows you to pass static instances of your objects around betwween other classes without having to instantiate a new object each time (thus allowing you to use the properties from the original instance without worry that they no longer contain the values you expected them to).
-m
delayedinsanity is offline  
Reply With Quote
Old 05-05-2008, 10:12 PM   #6 (permalink)
The Frequenter
Newcomer 
 
xenon's Avatar
 
Join Date: Dec 2007
Location: Bucharest, Romania
Posts: 438
Thanks: 3
xenon is on a distinguished road
Default

I'd go for the Registry pattern. Registry pattern
__________________
I have optimistic thoughts, even though sometimes (if not always) life's a bitch.
xenon is offline  
Reply With Quote
Old 05-05-2008, 10:24 PM   #7 (permalink)
is cute and cuddly
 
delayedinsanity's Avatar
 
Join Date: Mar 2008
Location: Vegas, Baby
Posts: 963
Thanks: 31
delayedinsanity is on a distinguished road
Default

Quote:
Originally Posted by xenon View Post
I'd go for the Registry pattern. Registry pattern
Isn't that just another form of the singleton? It's basically what I'm doing, based off of what I learned about the singleton pattern - however instead of including a getInstance() function inside of all my classes, I simple built a superclass that lets me grab whatever instance I want, and stores it all in a static array.

It looks a lot like yours, except I only have two methods I use, loadParent, and load, which looks like;

PHP Code:
static function &load ($szModule$szClass$szArgs=null) {

    
$szFilename "{$szModule}.{$szClass}.php";
    
$szClass    "kePhoto_{$szModule}_{$szClass}";

    if (
array_key_exists($szClassself::$m_aInstance)) {
        
$pInstance =& self::$m_aInstance[$szClass];

    } else {

        if (!
class_exists($szClass)) {
            
$szPath PATH_TO_LIB."/{$szFilename}";
            include(
$szPath);
        }

        
self::$m_aInstance[$szClass] =  new $szClass($szArgs);
        
$pInstance               =& self::$m_aInstance[$szClass];
    }
    
    return 
$pInstance;
            

delayedinsanity is offline  
Reply With Quote
Old 05-06-2008, 02:26 PM   #8 (permalink)
The Contributor
 
Evulness's Avatar
 
Join Date: Apr 2008
Location: Tampa, FL
Posts: 65
Thanks: 6
Evulness is on a distinguished road
Default

well, i just read some of the stuff on that link you gave, to the singleton stuff...
if i understood it right..

their example:
Code:
<?php

static function borrowBook() {
if (FALSE == self::$isLoanedOut){
    if (NULL == self::$book){
        self::$book = new BookSingleton();
    }
    self::$isLoanedOut = TRUE;
        return self::$book;
}else{
        return NULL;
    }
}

?>
is the key to do the loading right

so in my case, i would call and set my session class in this mannor, and use it in my user class, which is extended from my mysql class...
using something like their example
Code:
<?php
function borrowBook(){
$this->borrowedBook = BookSingleton::borrowBook();
    if ($this->borrowedBook == NULL) {
        $this->haveBook = FALSE;
    }
    else
        {
            $this->haveBook = TRUE;
    }
}
?>
right? obviously not THAT code, but i've already got an idea how to set it up... i'll go play with it, and come back and see what someone has to say
__________________
"Knowledge is power. Abuse it."~Evulness
My portfolio: www.evularts.com
Send a message via AIM to Evulness
Evulness is offline  
Reply With Quote
Old 05-06-2008, 04:27 PM   #9 (permalink)
is cute and cuddly
 
delayedinsanity's Avatar
 
Join Date: Mar 2008
Location: Vegas, Baby
Posts: 963
Thanks: 31
delayedinsanity is on a distinguished road
Default

The basic premise is that you have a static instance of the object, with a method to help you obtain that static instance. This way, once the object is loaded for the first time in your page, you can then call it by reference anywhere else in the page, including from inside other objects, and it will always return a reference to the same instance. This way any properties of the object being called will remain the same (static) from the time you first call it, till the end of the script execution. At least that's what I understand of it.

The method of doing it, that's apparently a little more up for debate than I originally suspected. The Singleton Design Pattern for PHP
illustrates a few ways, one of which also seems to be synonymous with the above mentioned registry pattern.

Whichever method you choose to go with, the singleton, or the singleton registry, I personally think both have their merits. This could be from a novice point of view however, as the more I study, the more I come across people who are (self proclaimed at least) experts crying the woes of the singleton because of how it resembles a global. I've read claims on how you should avoid this at all costs, but I've come to ignore them a bit since A) it works great for me, and B) if Zend Framework incorporates singletons, despite my dislike of frameworks, I'm sure it's not that evil.
-m
delayedinsanity is offline  
Reply With Quote
Old 05-06-2008, 06:38 PM   #10 (permalink)
The Contributor
 
Evulness's Avatar
 
Join Date: Apr 2008
Location: Tampa, FL
Posts: 65
Thanks: 6
Evulness is on a distinguished road
Default

Thanks man.
__________________
"Knowledge is power. Abuse it."~Evulness
My portfolio: www.evularts.com
Send a message via AIM to Evulness
Evulness is offline  
Reply With Quote
Old 05-06-2008, 06:42 PM   #11 (permalink)
The Prestige
Advanced Programmer Top Contributor Good Samaritan 
 
sketchMedia's Avatar
 
Join Date: Oct 2007
Location: Manchester, UK
Posts: 854
Thanks: 32
sketchMedia is on a distinguished road
Default

A singleton is an object that can only exsist once (normal classes can have many instance of the same type), this is designed to provide a 'global' point of access to the singleton object instance amongst other things.

The registry pattern doesnt have to be a singleton all it does is provide a single place to hold system vars (much like the windows registry); however combining these two patterns together can be very powerful for example instead of having to pass the registry object around in class contructors you can use a global 'getter' i.e.
PHP Code:
//dummy registry using a singleton
class registry
{
    private 
$pSelf;
    private function 
__contruct() {}
    private function 
__clone() {}
    public static function 
getInstance()
    {
          if(!
self::$pSelf instanceof self)
          {
               
self::$pSelf = new self;
           }
           return 
self::$pSelf;
    }

therefore:
PHP Code:
class test
{
    private 
$registry;
    public function 
__construct(registry $registry)
    {
        
$this->registry $registry;
    }
}
$registry = new registry();
$test = new test($registry); 
would be replaced by :
PHP Code:
class test
{
    private 
$registry;
    public function 
__construct()
    {
        
$this->registry registry::getInstance();
    }
}
$test = new test(); 
Btw in an example someone posted previoulsy contianed PHP5 E_STRICT errors because of the use of the '&' reference operator; PHP5 passes objects automatically by reference thus '&' in this context has been depreciated and produces an E_STRICT warning.


Edit: due to my brain not working properly most of the above mentioned code wont produce errors although using '&' to get a reference of an object is not needed as of PHP5, '$obj =& new obj();' will however return a strict error
__________________
mysql> SELECT * FROM `users` WHERE `users`.`clue` > 0;
Empty set (0.00 sec)

Last edited by sketchMedia : 05-06-2008 at 07:37 PM.
sketchMedia is offline  
Reply With Quote
The Following User Says Thank You to sketchMedia For This Useful Post:
delayedinsanity (05-06-2008)
Old 05-06-2008, 06:54 PM   #12 (permalink)
is cute and cuddly
 
delayedinsanity's Avatar
 
Join Date: Mar 2008
Location: Vegas, Baby
Posts: 963
Thanks: 31
delayedinsanity is on a distinguished road
Default

If you were referring to mine example, and keep in mind I'm not saying the code is perfect, but it doesn't produce any error or notice et al. I have error_reporting set to E_ALL and E_STRICT and it's outputting to a log file... the only thing in my log file is telling me that apparently it can't find my exif library. Which I should fix.

Like I said though, this isn't to say I don't believe you, just that it's not actually producing any errors. I should then be able to remove the reference operator in both the method name and when I pass it from the library to $pInstance and it'll still function the same?

EDIT: Well I'll be. I haven't needed that little ampersand this whole time! The funny thing is I didn't fully understand what it did when I first started using it, and I've come to like it because I can spot my object calls out of dozens of lines of code just because of that little =& combination. *sniffle* I'm kind of sad to see it go... though it doesn't produce any errors, like I was saying, so maybe I'll keep the lil fella around a bit longer. I dunno.
-m
delayedinsanity is offline  
Reply With Quote
Old 05-06-2008, 07:00 PM   #13 (permalink)
The Prestige
Advanced Programmer Top Contributor Good Samaritan 
 
sketchMedia's Avatar
 
Join Date: Oct 2007
Location: Manchester, UK
Posts: 854
Thanks: 32
sketchMedia is on a distinguished road
Default

sorry i forgot, i think its only on the 'new' keyword, but still the language is supposed to pass objects around by ref automatically hence why they implemented the 'clone' keyword to allow people to create copies of objects as the PHP4 way no longer works. im a little rusty with PHP atm been doing too much javascripting lately :D
__________________
mysql> SELECT * FROM `users` WHERE `users`.`clue` > 0;
Empty set (0.00 sec)
sketchMedia is offline  
Reply With Quote
Old 05-06-2008, 07:06 PM   #14 (permalink)
is cute and cuddly
 
delayedinsanity's Avatar
 
Join Date: Mar 2008
Location: Vegas, Baby
Posts: 963
Thanks: 31
delayedinsanity is on a distinguished road
Default

It started producing errors when I removed it from the load() method but it was still in my pages and other classes. So now I gotta go through and remove it from a whole bunch of places... *sigh* most of my work isn't even going forward, it's learning something new and going backwards to revamp all my existing code.

Oh well, that gave me an excuse to optimize my load() method. Here's the new one, should be error free, me thinks?

PHP Code:
static function load ($szModule$szClass$szArgs=null) {

    
$szFilename "{$szModule}.{$szClass}.php";
    
$szClass    "kePhoto_{$szModule}_{$szClass}";

    if (!
array_key_exists($szClassself::$Library)) {

        if (!
class_exists($szClass)) include(PATH_TO_LIB."/{$szFilename}");
        
self::$Library[$szClass] = new $szClass($szArgs);

    }
    
    return 
self::$Library[$szClass];
            

Doesn't look very complicated at all now. Maybe I'll include the old version of it in my sample code snippets that I send to prospective employers so they think it does more.
-m
delayedinsanity is offline  
Reply With Quote
Old 05-06-2008, 07:17 PM   #15 (permalink)
The Prestige
Advanced Programmer Top Contributor Good Samaritan 
 
sketchMedia's Avatar
 
Join Date: Oct 2007
Location: Manchester, UK
Posts: 854
Thanks: 32
sketchMedia is on a distinguished road
Default

Quote:
it's learning something new and going backwards to revamp all my existing code
I know how you feel.
Been trying to find it in the manual where it mentions PHP5's '&new' E_STRICT but i cant, it did used to be in there :s

I wasnt having a go at you before mate, just wanted to let you know that PHP5 doesnt need the & for objects i didnt word it very well i must admit.
__________________
mysql> SELECT * FROM `users` WHERE `users`.`clue` > 0;
Empty set (0.00 sec)
sketchMedia is offline  
Reply With Quote
Old 05-06-2008, 07:21 PM   #16 (permalink)
is cute and cuddly
 
delayedinsanity's Avatar
 
Join Date: Mar 2008
Location: Vegas, Baby
Posts: 963
Thanks: 31
delayedinsanity is on a distinguished road
Default

No trust me, you worded it just fine, and I found it helpful too, because I didn't know that. I briefly skimmed over something that said that in the new book I'm reading, but it didn't register until just now.

It did take a little of the magic out of my singleton->registry evolution though, haha. I just modified my load() *again* quickly, and it's gone from being 21 lines at the start of today to 10 lines as of now. Like I said, I'll just keep the more complicated version on the shelf to show to employers. They can go ooo, aah, and then I can optimize things later.
-m
delayedinsanity is offline  
Reply With Quote
Old 05-09-2008, 02:07 AM   #17 (permalink)
The Contributor
 
Evulness's Avatar
 
Join Date: Apr 2008
Location: Tampa, FL
Posts: 65
Thanks: 6
Evulness is on a distinguished road
Default

Ok, let me see if i get this right...

by adding the getInstance function, to each class, like the following
Code:
class EvulDB{
private static $m_pInst;

private function __construct(){ "......"}

public static function getInst()
    {
        if (!self::$m_pInst)
        {
            self::$m_pInst = new EvulDB();
        }

        return self::$m_pInst;
    }
function Connect ($sqlloginstuff) {  "......" }
function query($sql){ "query stuff" }
}//end class
doing this again, in my session class...
would alow me to do something like this in my user class?
Code:
include_once('Evuldb.php');
include_once('EvulSession.php');

class EvulUser extends EvulDB{
public static $EvSession;
public static $EvDbase;

public static function __construct(){
$EvSession = Session::getInst();
$EvDbase = Database::getInst();
}

public static function LoginUser(....){
 if ($EvDbase->query(..login query..)){
       $EvSession->set_var(stuff);
      }
}
}//end class
would something like that work? that is how i'm understanding the idea of the singleton so far... or rather, how i want to do this...
mind you i'm on a laptop, without access to my test server, so i can't fully write something up, and see if i can get the idea to work... but generaly speaking... is that the route i want to go?
__________________
"Knowledge is power. Abuse it."~Evulness
My portfolio: www.evularts.com
Send a message via AIM to Evulness
Evulness is offline  
Reply With Quote
Old 05-09-2008, 04:12 AM   #18 (permalink)
is cute and cuddly
 
delayedinsanity's Avatar
 
Join Date: Mar 2008
Location: Vegas, Baby
Posts: 963
Thanks: 31
delayedinsanity is on a distinguished road
Default

You probably already know this, but the static method call has to use the same name as the class you're making the call to. So Database::getInst() will return an error, but EvulDB::getInst() will work fine.

Your correct on how to go about that, but I did notice one other thing - your EvulUser class extends your EvulDB class, so there shouldn't be a need to call an instance of EvulDB from within it. You can just use $this to access all the parent methods and properties.

Oh, also, how come you don't have a local test server set up on your laptop? It saves a hell of a headache tracking down all the little typo's and what not if you can just switch over to your browser and test the latest updates.
-m
delayedinsanity is offline  
Reply With Quote
The Following User Says Thank You to delayedinsanity For This Useful Post:
Evulness (05-09-2008)
Old 05-09-2008, 10:21 AM   #19 (permalink)
The Frequenter
Newcomer 
 
xenon's Avatar
 
Join Date: Dec 2007
Location: Bucharest, Romania
Posts: 438
Thanks: 3
xenon is on a distinguished road
Default

Evulness, I recommend you change the following line in your getInst method:

PHP Code:
self::$m_pInst = new EvulDB(); 
to:

PHP Code:
self::$m_pInst = new self(); 
That way, when extending the base class, you won't need to reimplement the getInst() method (in the actual form, it would return an instance of the EvulDB class, even if you are in an subclass of it, therefore causing a bug in your application).
__________________
I have optimistic thoughts, even though sometimes (if not always) life's a bitch.
xenon is offline  
Reply With Quote
The Following User Says Thank You to xenon For This Useful Post:
Evulness (05-09-2008)
Old 05-09-2008, 03:30 PM   #20 (permalink)
The Contributor
 
Evulness's Avatar
 
Join Date: Apr 2008
Location: Tampa, FL
Posts: 65
Thanks: 6
Evulness is on a distinguished road
Default

so i would
Code:
self::$m_pInst = new self(); 
but when i call i would use
Code:
$EvulSys = EvulSession::getInst();
then when ever i need to use the methods from session in sys, i would just call something like...

$EvulSys->set_var("user_name", "Guest");


hows this look...

I am still writing it up on my linux box, but this is what i have so far, haven't tested what i have, but if i'm understanding things right... my next post will be saying it worked :)


Evuldb.php
Code:
<?php
class Evuldb{

private static $EvInst;

//construct & Connect to $host immediatly
function __construct(){
$this->Connect();
}

public static function getInst(){
if (!self::$EvInst) self::$EvInst = new self();
    return self::EvInst;
}

function Connect () { .. connect stuff... }
//other methods etc...
}
?>
EvulSess.php
Code:
<?php
class EvulSession {
private static $EvInst;

//construct class & Start a session immediatly
function __construct(){
    session_start();
}
public static function getInst(){
if (!self::$EvInst) self::$EvInst = new self();
    return self::EvInst;
}
//other methods for session bwlow
}
?>
and Evulsys.php

Code:
<?php
include_once 'Evuldb.php';
include_once 'EvulSess.php';
class EvulSys extends Evuldb {

// declare variables
var $EvulSys;
public static $EvSession;
public static $EvDbase;

//construct & set session & Connect to DB 
function __construct(){
$EvSession = EvulSession::getInst();
$EvulSys = $this->Connect();
}
//do login & other methods
}
?>
oh, i was thinking... i don't HAVE to do that on construct right? i can do that at anytime, in any method? and the instance will only be loaded and used when the method i use, sets the ::getInst()?
__________________
"Knowledge is power. Abuse it."~Evulness
My portfolio: www.evularts.com
Send a message via AIM to Evulness
Evulness is offline  
Reply With Quote
Reply



Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


All times are GMT. The time now is 02:42 AM.

 
     

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.1.0
Inactive Reminders By Icora Web Design