简体   繁体   中英

PDO alternative to mysql_ for getting field info

When I learned php, I learned from apparently older guides and have been using mysql_ functions. I'm switching everything over to PDO and I have a function I really want to keep but I can't quite figure out how to change it. This is the mysql_ function.

function getfield($field){
  $query = "SELECT $field FROM users WHERE id='".$_SESSION['user_id']."'";
  if($query_run = mysql_query($query)){
     if ($query_result = mysql_result($query_run, 0, $field)){
      return $query_result;
     }
  }

}

And from this I can get any field I want. However it's using the mysql_ stuff which I hear is deprecated and will soon be on its way out. This function gets the session ID from when you log in, and then using this session info, gathers all the information from that user.

Here is a quick example of your function using PDO. I've left some comments in code to help you grasp the idea.

function getField($field) {
    // Assuming you already obtained your connection here.
    // For the purpose of showing you an example I will name my database connection with variable $db

    // First check if we have user_id in our session, and then sanitize it.
    // never query the database with unsanitized data. 
    $userId = isset($_SESSION['user_id']) ? filter_var($_SESSION['user_id'], FILTER_SANITIZE_NUMBER_INT) : null;

    // If the user_id is not presented, then we don't need to query the database at all. Return null or whatever suits your needs
    if( ! $userId ) {
        return null;
    }

    // Build the query
    $sql = sprintf(
        "SELECT `%s` FROM `users` WHERE `id` = :userId LIMIT 1",
        $field
    );

    // Prepare the statement to be executed
    // More to read about prepared statements: http://php.net/manual/en/pdo.prepare.php
    $query = $db->prepare($sql);

    // Pass the user id to our prepared query
    // More to read about binding parameters: http://php.net/manual/en/pdostatement.bindparam.php
    $query->bindParam(':userId', $userId);

    // Execute the query
    $query->execute();

    // Return single result
    return $query->fetch(PDO::FETCH_ASSOC);
}

If you have any questions, don't hesitate to ask.

- Update as per OP comment -

Using the above function you will end up getting an array result for the following reasons:

  • ->fetch() combined with PDO::FETCH_ASSOC option will return an array with single item in it if result is being found. The key in that array would be the in this case the field name.

Now you can either access the value with something like this:

$result = getField('username');
print $result['username'];

or in your function:

$result = $query->fetch(PDO::FETCH_ASSOC);
if( isset($result[ $field ] ) {
    return $result[ $field ];
}

return null;

There are 2 possibilities to achieve your goal:

Option 1 SELECT * So your function could be something like:

function getfield($field){
    $res = null;

    $dsn = 'mydb';
    $user = '';
    $password = '';

    $dbh = new PDO($dsn, $user, $password);

    $query = "SELECT * FROM users WHERE id = ?";
    $stmt = $dbh->prepare($query);
    $stmt->bindValue(1,$_SESSION['user_id']);
    $stmt->execute();
    if ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        if (isset($row[$field])) 
           $res = $row[$field];
    }
    return $res;
}

Option 2 Predefined accepted column names:

function getfield($field){
    $acceptedArr = array('name','date_of_birth','age');
    $res = null;
    if (in_array($field,$acceptedArr)) {

      $dsn = 'mydb';
      $user = '';
      $password = '';

      $dbh = new PDO($dsn, $user, $password);

      $query = "SELECT $field FROM users WHERE id = ?";
      $stmt = $dbh->prepare($query);
      $stmt->bindValue(1,$_SESSION['user_id']);
      $stmt->execute();
      if ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        $res = $row[$field];
      }
    }
    return $res;
}

I would prefer 1st variant.

There are many ways to do it. One more is:

function getfield(PDO $dbh, $field) {
    return $dbh->query(
        'SELECT `' . str_replace('`', '``', $field) . '` FROM users WHERE id = ' . intval($_SESSION['user_id'])
    )->fetchColumn();
}

Remember there is no more internal global connection and it is a really bad idea to create one at each function call as Alex did. Here, we just pass it as argument.

Also, it would be a good idea to protect $field .

I suppose we can assume that existence (isset) of $_SESSION['user_id'] is checked before somewhere else.

Finally, PDOStatement::fetchColumn is the nearest equivalent of mysql_result but doesn't work exactly the same.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM