Solved

repeated code in the methods.  Create another method

Posted on 2013-11-22
16
228 Views
Last Modified: 2013-12-06
<?php
  class users{
    
    contstructor{}
    
    public function do_something(username,sql){
      if (username is not in the method){
        //grab username from cookie
      }
    }
    
    public function print(username,sql){
      if (username is not in the method){
        //grab username from cookie
      }
    }    
    
    
  }

Open in new window


this is in every method, getting the username
code is being repeated many times

      if (username is not in the method){
        //grab username from cookie
      }

Open in new window



can this be somewhere in the constructor or maybe a cookie check method (but how can the cookie check method let the current method know that the cookie check method found the username?)






Please do not give an answer requiring username in the method
because I want to learn more about object oriented programming.

I am not looking for a content management system or existing code that gets around this issue.  I want to learn object oriented programming.
0
Comment
Question by:rgb192
  • 8
  • 5
  • 3
16 Comments
 
LVL 108

Expert Comment

by:Ray Paseur
Comment Utility
You would want to make the user name be a property of the object.  Something prefixed with $this-> will be available to all methods in the object and all classes that extend the parent class.
0
 
LVL 20

Assisted Solution

by:Mark Brady
Mark Brady earned 333 total points
Comment Utility
Here is a simple class you can play with. It will check for a cookie called 'some_cookie_name'. If it finds it, the class property ($this->username) is set from the value in the cookie.

If not then you have to set it some other way so in my example I look for it in a post or get (I use $_REQUEST as that will capture post and get from a form or a URL.

Try it out. Once the username is set it then saves a cookie with the username to the users computer. I made it expire in 24 hours but you can set whatever you want for this value.

Lastly, when you have saved this into a file go to the url of the script but append the url with ?username='Mark' then run it.

Once it has run take the ?username=Mark off the url and run it again.

It will still display the username.

Pretty straight forward stuff but it should get you started. Good luck.

<?php

// instantiate the class object
$user = new User();

// call its run method (function)
$user->run();

// the end.....

class User {
    private $username;

    public function __construct() {
        // check for a cookie
        $cookie = 'some_cookie_name';
        $this->username = isset($_COOKIE[$cookie]) ? $_COOKIE[$cookie] : false;
        
        if (!$this->username) {

            // cookie was not found so you will need to get username from somewhere else
            // once you have it set its value to the $this->username
            // example
            $this->username = isset($_REQUEST['username']) ? $_REQUEST['username'] : 'Unknown';
            // now save it into a cookie
            
            // set an expirey time if you want
            $expireson = strtotime(gmdate('Y-m-d H:i:s') + 86400); // make it expire in 24 hours
            $result = setcookie($cookie, $this->username, $expireson, '/');
            var_dump($result);
        }
    }
    
    public function run() {
        echo 'Hello '.$this->username;
    }
}

?>

Open in new window


actually replace the expireson line with this
$expireson = strtotime(date('Y-m-d H:i:s')) + 86400; // make it expire in 24 hours

Open in new window

0
 
LVL 20

Expert Comment

by:Mark Brady
Comment Utility
Have you tried my code yet?
0
 

Author Comment

by:rgb192
Comment Utility
no cookie:
bool(true) Hello Unknown

cookie:

Hello Unknown

when I do
?username=Mark
no cookie:
bool(true) Hello Mark
cookie:
Hello Mark


but I do not fully understand
0
 
LVL 108

Expert Comment

by:Ray Paseur
Comment Utility
Let me try to set the table a little better here.  The word property is a term of art in object oriented programming.  It refers to variables that are present in an object and are available to all of the methods of the object.  There are three kinds of properties: private, protected and public.

Private properties are visible to the class that defines them and no other.  A class that extends the parent class will fire a fatal error if it tries to use a parent class private property, as will any other class that illegally accesses a private property.  Private means private, period.

Protected properties are available to the class that defines them and any class that extends the class that defines them.  Your "default" setting for properties should probably be protected, but PHP makes the default public.   So you have to specify protected if you want that level of visibility.

Public properties are available to anybody.  Any class, any scope, so long as you can access the object, you can retrieve or mutate the public properties.

Now in your case, you want to "grab username from cookie."  That is a bad design pattern because information in cookies should be like data base keys.  They should not carry meaningful data like a "username", nor anything except pointers to data on the server.  But let's put that design flaw aside and just look at accessing the cookie data.  In PHP $_COOKIE is a superglobal variable, and it is an array.  A superglobal variable is public in every scope and namespace.  So, technically, you don't need a method to access and store the data that is in $_COOKIE, except as an abstraction layer.  The notion of an abstraction layer for the $_COOKIE makes sense to me.  Someday you might want to test by changing the cookie name.

Your class could have a grabUserNameFromCookie() method that would find the cookie, get the value and store the value in a class property named userName.  Once this method has run, you can find the userName in every method of the class and potentially all extensions of the class in a variable named $this->userName.

I would recommend using a separate method to get the $this->userName property, so you can use mock objects for unit testing.
0
 
LVL 20

Expert Comment

by:Mark Brady
Comment Utility
As far as my example it was just to show you how you can do it but I agree with Ray, you should never store meaningful data in a cookie. They can be edited and changed and that could spell disaster for your sites security.

In my example if you comment out the var_dump on line 30 you will not get the bool(true) and will only get 'Hello Mark'

Instead of using php sessions in my commercial code I use a session class I build which is database driven and allows me greater controller over my users sessions and things like filling out forms but not competing them allows me to populate the form with what they have filled out if they go back there in the same session.

Storing something like a sessionid that you create yourself is a good idea. Then you can use that id to lookup their database record.

In any case that was a quick example of how to grab and set a cookie and assign it to a class property. In my case it was $this->username
0
 
LVL 108

Expert Comment

by:Ray Paseur
Comment Utility
Just a sidebar note about $_REQUEST... You probably do not want to use that variable because it may or may not contain external variables from predictable or unpredictable sources, depending on overlapping configuration values.  This is Antiphpractice #15.  See the notes here.
http://www.php.net/manual/en/ini.core.php#ini.request-order
http://www.php.net/manual/en/ini.core.php#ini.variables-order
0
 

Author Comment

by:rgb192
Comment Utility
okay, the code is not secure, but I do not know how to code works.  I am confused because I think the first step is for me to understand why code works and then create code that is more secure.

http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_28301325.html#a39679229

Could either of you answer these questions please.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 108

Expert Comment

by:Ray Paseur
Comment Utility
Please go back and check this one.
http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_28301325.html#a39668868

If I have a moment I will try to give you a code example.
0
 
LVL 20

Expert Comment

by:Mark Brady
Comment Utility
Sure I can. In the constructor method ( __construct()  ) of my example on line 17 the code looks for a stored cookie which contains a username.

If it finds it, the global variable $this->username has its value set to the username found in the cookie. In a php class a global variable is prepended with $this-> and then the variable name.

By doing that you can access this variables value from anywhere inside that class (even in private functions).

If the cookie was not found (maybe it has never been set or maybe it has expired) then it looks for a value sent ito the script via the URL or in my example I used $_REQUEST['username'] so that could be sent by a form which has its method set to 'post'.

What my example does is look for 'username=' and if it finds it the variable is set. If it does not find it then the username variable is set to 'Unknown'

If you pass in the username like www.yourscript.php?username=Sampson then the $this->username is set to 'Sampson' and that is saved in a cookie and available until the cookie expires.

If you don't pass it in then $this->username is set to 'Unknown' and that is saved into the cookie.

This is not a good practical example for the real world though as you would not want to set 'Unknown' into the cookie - it is not very useful. Each time you load the page AFTER you have set the username you will not need to pass it in as it will be found in the cookie until the cookie expires.

I hope that makes it clearer.
0
 
LVL 108

Expert Comment

by:Ray Paseur
Comment Utility
@elvin66: Your theory is good but please be careful about the terminology.  In PHP a global variable is something that is declared global or is a native superglobal like $_COOKIE.  There are a lot of bad things about global variables, notably that you cannot use mock objects to unit test them, and there is the risk of name collisions, so they are usually discouraged.

A better way to refer to things like $this->var is "property" of the object.
0
 
LVL 108

Accepted Solution

by:
Ray Paseur earned 167 total points
Comment Utility
This shows the example of using the class property "username" which can be shared among object instances of this class and any class that extends this class.  In the context of the classes and objects, we refer to the variable with $this->username.  PHP knows to make this variable visible according to the rules of public, protected or private.  In this case, we designate the property to be protected.

The constructor tries to find the username in the cookie.  If it cannot find the username, it substitutes "Anonymous User" and places the value into $this->username.

The DoSomething() method incorporates $this->username into a message string and returns the string.  Any other methods that care about the value of $this->username refer to it the same way.  It exists as a property of the object, therefore it does not need to be passed from one method to another.  It is known to all methods of the class, and if it is not private, it is known to all methods of any class that extends the parent class.

Note that inside the DoSomething() method we create a variable named $response.  But when you see the var_dump() output the $response variable is not visible.  That is because it is a local variable, known only to DoSomething(), and is not a property of the object.


<?php // RAY_temp_rgb192.php
error_reporting(E_ALL);

// SEE http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_28301325.html

Class User
{
    // THE USER NAME IS AVAILABLE TO EXTENSIONS
    protected $username;

    // THE USER NAME IS DETECTED BY THE CLASS CONSTRUCTOR
    public function __construct()
    {
        // LOCATE THE USERNAME OR "FALSE"
        $this->username = !empty($_COOKIE['username'])
                        ? $_COOKIE['username']
                        : 'Anonymous User'
                        ;
    }

    public function doSomething($str)
    {
        $response = "<br>$str on behalf of $this->username";
        return $response;
    }
}

// CREATE A NEW USER
$u = new user;

// DO SOMETHING AND SHOW THE RESULT
$output = $u->dosomething('Unit of Work');
print_r($output);

// VISUALIZE THE OBJECT
echo '<pre>';
var_dump($u);

Open in new window

0
 
LVL 20

Assisted Solution

by:Mark Brady
Mark Brady earned 333 total points
Comment Utility
@Ray - I didn't mean to refer to it as a suprglobal by any means. I was trying to explain how it is accessible from any method or place inside that class. For the methods (functions it is the same result as declaring a variable as global.

Just to clarify to the author, when a variable is available anywhere in a script that means its value can be modified from anywhere.  I think I'll stop now as I don't want to confuse the author :)
0
 
LVL 108

Expert Comment

by:Ray Paseur
Comment Utility
@elvin: 10-4.  Object oriented programming is confusing for everyone at first ;-)
0
 

Author Closing Comment

by:rgb192
Comment Utility
when a variable is available anywhere in a script that means its value can be modified from anywhere

Thanks
0
 
LVL 108

Expert Comment

by:Ray Paseur
Comment Utility
when a variable is available anywhere in a script that means its value can be modified from anywhere
FALSE!

Variable scope and visibility must be considered.
http://php.net/manual/en/language.variables.scope.php
http://php.net/manual/en/language.oop5.visibility.php
0

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Part of the Global Positioning System A geocode (https://developers.google.com/maps/documentation/geocoding/) is the major subset of a GPS coordinate (http://en.wikipedia.org/wiki/Global_Positioning_System), the other parts being the altitude and t…
Nothing in an HTTP request can be trusted, including HTTP headers and form data.  A form token is a tool that can be used to guard against request forgeries (CSRF).  This article shows an improved approach to form tokens, making it more difficult to…
The viewer will learn how to count occurrences of each item in an array.
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now