25

I'd like to know how to select a single value from my MySQL table. The table includes columns username and id amongst others (id is auto-increment and username is unique). Given the username, I want to set a session variable $_SESSION['myid'] equal to the value in the id column that corresponds to the given username. Here's the code that I've already tried:

session_start();
$name = $_GET["username"];
$sql = "SELECT 'id' FROM Users WHERE username='$name'";
$result = mysql_query($sql);
$value = mysql_fetch_object($result);
$_SESSION['myid'] = $value;

So far I'm getting:

Catchable fatal error: Object of class stdClass could not be converted to string.

Casting $value to type string does not fix the problem.

Dharman
  • 30,962
  • 25
  • 85
  • 135
user3055501
  • 315
  • 2
  • 5
  • 7
  • Just a reminder... The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead – Wes Cossick Jan 02 '14 at 07:16
  • 2
    This has serious security problems. As @WesC points out, don't use the mysql_* functions. Also, you are wide open to SQL injection attacks. – elixenide Jan 02 '14 at 07:17

8 Answers8

60
  1. Don't use quotation in a field name or table name inside the query.

  2. After fetching an object you need to access object attributes/properties (in your case id) by attributes/properties name.

One note: please use mysqli_* or PDO since mysql_* deprecated. Here it is using mysqli:

session_start();
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$link = new mysqli('localhost', 'username', 'password', 'db_name');
$link->set_charset('utf8mb4'); // always set the charset
$name = $_GET["username"];
$stmt = $link->prepare("SELECT id FROM Users WHERE username=? limit 1");
$stmt->bind_param('s', $name);
$stmt->execute();
$result = $stmt->get_result();
$value = $result->fetch_object();
$_SESSION['myid'] = $value->id;

Bonus tips: Use limit 1 for this type of scenario, it will save execution time :)

Dharman
  • 30,962
  • 25
  • 85
  • 135
Awlad Liton
  • 9,366
  • 2
  • 27
  • 53
11

The mysql_* functions are deprecated and unsafe. The code in your question in vulnerable to injection attacks. It is highly recommended that you use the PDO extension instead, like so:

session_start();

$query = "SELECT 'id' FROM Users WHERE username = :name LIMIT 1";
$statement = $PDO->prepare($query);
$params = array(
    'name' => $_GET["username"]
);
$statement->execute($params);
$user_data = $statement->fetch();

$_SESSION['myid'] = $user_data['id'];

Where $PDO is your PDO object variable. See https://www.php.net/pdo_mysql for more information about PHP and PDO.

For extra help:

Here's a jumpstart on how to connect to your database using PDO:

$database_username = "YOUR_USERNAME";
$database_password = "YOUR_PASSWORD";
$database_info = "mysql:host=localhost;dbname=YOUR_DATABASE_NAME";
try
{
    $PDO = new PDO($database_info, $database_username, $database_password);
}
catch(PDOException $e)
{
    // Handle error here
}
Dharman
  • 30,962
  • 25
  • 85
  • 135
Wes Cossick
  • 2,923
  • 2
  • 20
  • 35
  • Thanks for the answer Wes. I'll definitely look into PDO when I have more time. – user3055501 Jan 02 '14 at 07:31
  • From personal experience, I recommend you look into it sooner rather than later. The more code you write using the `mysql_*` functions, the more you'll find out that you'll be required to entirely rewrite. Plus, it's actually pretty convenient and more organized in other areas. – Wes Cossick Jan 02 '14 at 07:33
  • 1
    in case someone else sees this and panics, you can change to mysqli instead which is better. note the i at the end of mysql – Anders M. Oct 15 '14 at 01:19
  • Like @AndersM said - I also find mysqli easier to use/read than PDO, for simple queries. Note however that Wes is making a very important point: if any part of your query includes text that is not 100% under your control, then *use a prepared statement*. In mysqli, that is `prepare`, [manual discussion of prepared statements](http://php.net/manual/en/mysqli.quickstart.prepared-statements.php) – ToolmakerSteve Jan 09 '17 at 21:05
4

You do this by using mysqli_fetch_field method.

session_start();
$link = mysqli_connect("localhost", "my_user", "my_password", "world");
$name = $_GET["username"];
$sql = "SELECT 'id' FROM Users WHERE username='$name' limit 1";
$result = mysqli_query($link, $sql);
if ($result !== false) {
    $value = mysqli_fetch_field($result);
    $_SESSION['myid'] = $value;
}

Note: you can do that by using mysql_fetch_field() method as well, but it will be deprecated in php v5.5

ToolmakerSteve
  • 18,547
  • 14
  • 94
  • 196
sas
  • 2,563
  • 1
  • 20
  • 28
  • 2
    mysqli_fetch_field "Returns an object which contains field definition information or FALSE if no field information is available." so this won't work as suggested by the answer. -1 because of this. – El Gucs Sep 28 '16 at 09:11
  • 1
    @GusstavvGil: I've corrected the code by making sure there is a valid $result, before the call to `mysqli_fetch_field`. I've also added the missing $link parameter. – ToolmakerSteve Jan 09 '17 at 20:51
  • 4
    @ToolmakerSteve mysqli_fetch_field does not return the value. It returns the field definition, like name, table, flags. -1 because of this... http://php.net/manual/en/mysqli-result.fetch-field.php – commonpike Sep 14 '17 at 11:39
  • This answer should not be used because it is insecure/unstable. – mickmackusa Jan 24 '20 at 09:35
  • 2
    **Warning:** This answer is totally wrong. `mysqli_fetch_field()` returns metadata about a table column, not the value itself. – Dharman Apr 06 '20 at 20:12
4

mysql_* extension has been deprecated in 2013 and removed completely from PHP in 2018. You have two alternatives PDO or MySQLi.

PDO

The simpler option is PDO which has a neat helper function fetchColumn():

$stmt = $pdo->prepare("SELECT id FROM Users WHERE username=?");
$stmt->execute([ $_GET["username"] ]);
$value = $stmt->fetchColumn();

Proper PDO tutorial

MySQLi

You can do the same with MySQLi, but it is more complicated:

$stmt = $mysqliConn->prepare('SELECT id FROM Users WHERE username=?');
$stmt->bind_param("s", $_GET["username"]);
$stmt->execute();
$data = $stmt->get_result()->fetch_assoc();
$value = $data ? $data['id'] : null;

fetch_assoc() could return NULL if there are no rows returned from the DB, which is why I check with ternary if there was any data returned.

Since PHP 8.1 you can also use fetch_column()

$stmt->execute();
$value = $stmt->get_result()->fetch_column();
Dharman
  • 30,962
  • 25
  • 85
  • 135
  • https://stackoverflow.com/questions/59893254/get-id-from-mysql-database-and-load-data-based-on-it?noredirect=1#comment105915322_59893254 (it is surprisingly hard to find secure queries to close new questions with.) – mickmackusa Jan 24 '20 at 09:46
3

Try this

$value = mysql_result($result, 0);
Khawer Zeshan
  • 9,470
  • 6
  • 40
  • 63
  • **Warning:** `mysql_*` extension is deprecated as of PHP 5.5.0, and has been removed as of PHP 7.0.0. Instead, either the [mysqli](https://www.php.net/manual/en/book.mysqli.php) or [PDO_MySQL](https://www.php.net/manual/en/book.pdo.php) extension should be used. See also the [MySQL API Overview](https://www.php.net/manual/en/mysqlinfo.api.choosing.php) for further help while choosing a MySQL API. – Dharman Apr 06 '20 at 20:13
  • "Try this" answers are low-value on Stackoverflow because they do a poor job of educating/empowering the OP and thousands of future researchers. Even if you feel your solution is ultra-basic/self-explanatory, ALL answers should include some form of plain English supporting text. Tell researchers how it works, why it works, how it is different from other answers, why you think it is a good idea, provide link(s) to documentation, etc. Simply be generous when you answer with the intent to help people and role model good answer posting behaviour to others. – mickmackusa Apr 06 '20 at 21:09
2

When you use mysql_fetch_object, you get an object (of class stdClass) with all fields for the row inside of it.

Use mysql_fetch_field instead of mysql_fetch_object, that will give you the first field of the result set (id in your case). The docs are here

Alex Siri
  • 2,856
  • 1
  • 19
  • 24
  • 1
    **Warning:** This answer is totally wrong. `mysql_fetch_field()` returns metadata about a table column, not the value itself. – Dharman Apr 06 '20 at 20:12
2

It is quite evident that there is only a single id corresponding to a single username because username is unique.

But the actual problem lies in the query itself-

$sql = "SELECT 'id' FROM Users WHERE username='$name'";

O/P

+----+
| id |
+----+
| id |
+----+

i.e. 'id' actually is treated as a string not as the id attribute.

Correct synatx:

$sql = "SELECT `id` FROM Users WHERE username='$name'";

i.e. use grave accent(`) instead of single quote(').

or

$sql = "SELECT id FROM Users WHERE username='$name'";

Complete code

session_start();
$name = $_GET["username"];
$sql = "SELECT `id` FROM Users WHERE username='$name'";
$result = mysql_query($sql);
$row=mysql_fetch_array($result)
$value = $row[0];
$_SESSION['myid'] = $value;
Rajesh Paul
  • 6,793
  • 6
  • 40
  • 57
  • 2
    Needs a ; on the fifth line. – Brian Fleming May 29 '18 at 02:35
  • **Warning:** `mysql_*` extension is deprecated as of PHP 5.5.0, and has been removed as of PHP 7.0.0. Instead, either the [mysqli](https://www.php.net/manual/en/book.mysqli.php) or [PDO_MySQL](https://www.php.net/manual/en/book.pdo.php) extension should be used. See also the [MySQL API Overview](https://www.php.net/manual/en/mysqlinfo.api.choosing.php) for further help while choosing a MySQL API. – Dharman Apr 06 '20 at 20:08
1

try this

session_start();
$name = $_GET["username"];
$sql = "SELECT 'id' FROM Users WHERE username='$name' LIMIT 1 ";
$result = mysql_query($sql) or die(mysql_error());
if($row = mysql_fetch_assoc($result))
{
      $_SESSION['myid'] = $row['id'];
}
Satish Sharma
  • 9,547
  • 6
  • 29
  • 51
  • **Warning:** `mysql_*` extension is deprecated as of PHP 5.5.0, and has been removed as of PHP 7.0.0. Instead, either the [mysqli](https://www.php.net/manual/en/book.mysqli.php) or [PDO_MySQL](https://www.php.net/manual/en/book.pdo.php) extension should be used. See also the [MySQL API Overview](https://www.php.net/manual/en/mysqlinfo.api.choosing.php) for further help while choosing a MySQL API. – Dharman Apr 06 '20 at 20:08