3

security.php

class Security {

    public function sanitize($data) {
        return mysql_real_escape_string($data);
    }
}
?>

users.php

<?php


class User {

    private $db;

    public function __construct() {
        $this->db = new Connection();
        $this->db = $this->db->dbConnect();
    }

    public function userExists($username) {
        $username = sanitize($username);
        $st = $this->db->prepare("SELECT * FROM `users` WHERE `username`=? ");
        $st->bindParam(1, $username);
        $st->execute();

        if ($st->rowCount() == 1) {
                echo "User exists";
            } else {
                echo 'Incorrect username or password lad';
            }
    }
}

?>

in my user exists method i want to use sanitize method but im am unsure the correct way to do this in oop. both class are on a different file. any help appreciated.

PeeHaa
  • 71,436
  • 58
  • 190
  • 262
ivor
  • 61
  • 1
  • 5
  • Can you format your code please? – Pedrom Mar 20 '13 at 15:35
  • indent your code and to your general question if you have reference to that object just use it and call his function $cls1 = new Class1(); $cls1->func(); – Adidi Mar 20 '13 at 15:36
  • @Pedrom he's new, and someone has already suggested it. @ivor: `require_once` the file and then instantiate it (if not a static class) and `$cls->sanitize()` – Amelia Mar 20 '13 at 15:39
  • sorry about the formating issue "first post" – ivor Mar 20 '13 at 15:41
  • 7
    You do not need to do mysql_real_escape if you're using prepared statements. This can end up with parameters being double quoted and double \'d. – hsanders Mar 20 '13 at 15:42
  • 1
    hsanders is right; you're using prepared statements, so you don't need to escape this. And not only that, but you shouldn't be using `mysql_xxx()` functions in conjunction with more advanced DB libs like mysqli or pdo; the `mysql_real_escape_string()` may not even work at all, because it would expect you to have made a connection using `mysql_connect()`. Just get rid of it entirely. – SDC Mar 20 '13 at 15:56
  • @Hiroto Yeah that's why I asked for that (politely enough I hope), and there weren't any other comment when I posted mine. However, I am glad that he found it a way and that his questions got very detailed answers. – Pedrom Mar 20 '13 at 17:08

3 Answers3

3

My best suggestion would be to make the sanitize method in Security a static function. That way you can access the method without having to instantiate the object.

Example:

<?php
class Security {
  public static function sanitize($data) {
    return mysql_real_escape_string($data);
  }
}

And in your User class:

public function userExists($username) {
    $username = Security::sanitize($username);

Here is a full working example:

security.php

<?php
class Security {
  public static function sanitize($data) {
    return mysql_real_escape_string($data);
  }
}

users.php

<?php
class User {
  private $db;

  public function __construct() {
    $this->db = new Connection();
    $this->db = $this->db->dbConnect();
  }

  public function userExists($username) {
    $username = Security::sanitize($username);
    $st = $this->db->prepare("SELECT * FROM `users` WHERE `username`=? ");
    $st->bindParam(1, $username);
    $st->execute();

    if($st->rowCount() == 1) {
      return True;
    } else {
      return False;
    }
  }
}

test.php (see it in action!)

<?php
require_once 'security.php';
require_once 'user.php';

$user = new User();
$exists = $user->userExists('my-username');
if($exists) {
  print 'User exists';
} else {
  print 'Incorrect username or password lad';
}
Joshua Burns
  • 8,268
  • 4
  • 48
  • 61
  • 1
    This was a pretty common way to namespace functions, before PHP 5.3 officially [add them to the language](http://us.php.net/manual/en/language.namespaces.php). – Annika Backstrom Mar 20 '13 at 15:51
  • thanks for your fast response. now i understand static functions. – ivor Mar 20 '13 at 15:54
  • 2
    no problem. :) if you'd like to click that little green check mark next to my answer, this rewards me with fun little points which make me smile. – Joshua Burns Mar 20 '13 at 16:00
1

Well, include the file, properly instatiate the object and invoke its method.

<?php
require_once 'security.php';
class User {

private $db;

public function __construct() {
    $this->db = new Connection();
    $this->db = $this->db->dbConnect();
}

public function userExists($username) {
    $sec = new Security();
    $username = $sec->sanitize($username);
    $st = $this->db->prepare("SELECT * FROM `users` WHERE `username`=? ");
    $st->bindParam(1, $username);
    $st->execute();

    if ($st->rowCount() == 1) {
            echo "User exists";
        } else {
            echo 'Incorrect username or password lad';
        }
   }
}
Ramon K.
  • 3,402
  • 3
  • 20
  • 29
1

This may be a little long winded but it will shed some light on some topics that you will eventually want to learn.

Also you don't need to escape anything when you use prepared statements. But im going to answer your question anyways.

There are a number of ways to do this.

Dependency Injection

You could instantiate a Security instance like you did in your constructor with Connection. But this is the wrong way, because it makes your code depend on the Security class, like your class now depends on the Connection class

To fix this use dependency injection

public function __construct( DBInterface $db ) {
    $this->db = $db;
}

Use it like this

$connection = new Connection();
$db = $connection->dbConnect();
$user = new User( $db );

Now your code only depends on the DBInterface interface. You can now create any number of classes that implement that interface and pass them to the user class.

You could make the method in Security static but this also adds dependency on the Security class.

You could pass the security object in the constructor as well, but that could quickly get ugly. Take a look at dependency injection containers


Add the method to your connection class

Since you created your own Connection class you could add the escape method to the connection class and call it with $this->db->sanitize()

$username = $this->db->sanitize($username);

Traits in php 5.4

Trait Security {
    public function sanitize($data) {
        return mysql_real_escape_string($data);
    }
}

Class User {
    use Security;
...
}

Then use the methods of the Security trait as if they were in the User class.


I'm purposely not mentioning creating a base class and extending it because in this case with a User and a Security class it doesn't make sense.

Community
  • 1
  • 1
Galen
  • 29,976
  • 9
  • 71
  • 89