35

I am trying to write a function that will check for a single value in the db using mysqli without having to place it in an array. What else can I do besides what I am already doing here?

function getval($query){
    $mysqli = new mysqli();
    $mysqli->connect(HOST, USER, PASS, DB);
    $result = $mysqli->query($query);
    $value = $mysqli->fetch_array;
    $mysqli->close();
    return $value;
}
hjpotter92
  • 78,589
  • 36
  • 144
  • 183
Refiking
  • 641
  • 3
  • 10
  • 18

8 Answers8

41

How about

$name = $mysqli->query("SELECT name FROM contacts WHERE id = 5")->fetch_object()->name; 
assylias
  • 321,522
  • 82
  • 660
  • 783
Mike
  • 453
  • 4
  • 2
  • 5
    This is the shortest line of code for getting a mysqli result value. – Daniel Harris Feb 18 '16 at 16:38
  • 1
    This assumes that the scalar being returned has a known field name. This is not consistent with OP's code, which passes in ANY query (that is expected to return a single value; a "scalar" query). It might not even be a query of a record field - it could be returning a count, or even a system variable. – ToolmakerSteve Aug 03 '16 at 03:36
  • 2
    In case the `query` fails, this will cause a `Fatal error` (Call to a member function fetch_object() on boolean). – CodeBrauer May 08 '18 at 09:36
28

The mysql extension could do this using mysql_result, but mysqli has no equivalent function as of today, afaik. It always returns an array.

If I didn't just create the record, I do it this way:

$getID = mysqli_fetch_assoc(mysqli_query($link, "SELECT userID FROM users WHERE something = 'unique'"));
$userID = $getID['userID'];

Or if I did just create the record and the userID column is AI, I do:

$userID = mysqli_insert_id($link);
prl77
  • 665
  • 6
  • 8
  • 3
    Or change `assoc` to `array` and then you can do `$getID[0]` – rybo111 Mar 24 '14 at 23:40
  • 1
    And nobody, nobody, nobody cares that the only meaningful part of this long-sought "one-liner" is gone far beyond visible screen... – Your Common Sense Mar 25 '14 at 09:56
  • downvoted solely because `fetch_object()` existed many years before this answer, which returns a simple object, which means that at the time you wrote this mysqli did have a better option. Also your answer is written in procedural commands while OP's question was written via object-based mysqli. – skrilled Nov 30 '15 at 22:48
  • 1
    This assumes that the scalar being returned has a known field name. This is not consistent with OP's code, which passes in ANY query (that is expected to return a single value; a "scalar" query). It might not even be a query of a record field - it could be returning a count, or even a system variable. – ToolmakerSteve Aug 03 '16 at 03:36
7

Always best to create the connection once at the beginning and close at the end. Here's how I would implement your function.

$mysqli = new mysqli();
$mysqli->connect(HOSTNAME, USERNAME, PASSWORD, DATABASE);

$value_1 = get_value($mysqli,"SELECT ID FROM Table1 LIMIT 1");
$value_2 = get_value($mysqli,"SELECT ID FROM Table2 LIMIT 1");

$mysqli->close();

function get_value($mysqli, $sql) {
    $result = $mysqli->query($sql);
    $value = $result->fetch_array(MYSQLI_NUM);
    return is_array($value) ? $value[0] : "";
}
jbrahy
  • 4,228
  • 1
  • 42
  • 54
  • is MYSQLI_NUM a constant? – Gokigooooks Mar 14 '15 at 01:28
  • Yes, it is. http://stackoverflow.com/questions/1684993/what-does-mysqli-num-mean-and-do From php.net, "This optional parameter is a constant indicating what type of array should be produced from the current row data. The possible values for this parameter are the constants MYSQLI_ASSOC, MYSQLI_NUM, or MYSQLI_BOTH." – jbrahy Mar 15 '15 at 22:06
  • 1
    this answer, and the more recent answers by John and rybo111, are the only ones that directly address OP's code. OP's question shows a method that accepts ANY scalar-returning query -- does not require knowing name of a field to be returned. – ToolmakerSteve Aug 03 '16 at 04:07
5

Here's what I ended up with:

function get_col($sql){
  global $db;
  if(strpos(strtoupper($sql), 'LIMIT') === false) {
    $sql .= " LIMIT 1";
  }
  $query = mysqli_query($db, $sql);
  $row = mysqli_fetch_array($query);
  return $row[0];
}

This way, if you forget to include LIMIT 1 in your query (we've all done it), the function will append it.

Example usage:

$first_name = get_col("SELECT `first_name` FROM `people` WHERE `id`='123'");
rybo111
  • 12,240
  • 4
  • 61
  • 70
  • Minor issue: The query could contain `limit` (lowercase) instead of `LIMIT`. So if you use the part of the answer involving `LIMIT`, might want to make the test `if (strpos($sql, 'LIMIT') === false && strpos($sql, 'limit') === false) {` – ToolmakerSteve Aug 03 '16 at 04:01
  • @ToolmakerSteve Good spot - fixed using `strtoupper()`. – rybo111 Aug 03 '16 at 10:34
  • Let's just hope that there is no string literal in the SQL that happens to contain the string "limit". – trincot Oct 15 '16 at 22:03
  • @trincot True, it was an afterthought - the if statement could look for `LIMIT N` (where N is 0-9) using regexp instead. – rybo111 Oct 15 '16 at 22:14
3

Even this is an old topic, I don't see here pretty simple way I used to use for such assignment:

list($value) = $mysqli->fetch_array;

you can assign directly more variables, not just one and so you can avoid using arrays completely. See the php function list() for details.

John
  • 123
  • 1
  • 10
2

First and foremost,

Such a function should support prepared statements

Otherwise it will be horribly insecure.

Also, such a function should never connect on its own, but accept an existing connection variable as a parameter.

Given all the above, only acceptable way to call such a function would be be like

$name = getVal($mysqli, $query, [$param1, $param2]);

allowing $query to contain only placeholders, while the actual data has to be added separately. Any other variant, including all other answers posted here, should never be used.

function getVal($mysqli, $sql, $values = array())
{
    $stm = $mysqli->prepare($sql);
    if ($values)
    {
        $types = str_repeat("s", count($values));
        $stm->bind_param($types, ...$values);
    }
    $stm->execute();
    $stm->bind_result($ret);
    $stm->fetch();
    return $ret;
}

Which is used like this

$name = getVal("SELECT name FROM users WHERE id = ?", [$id]);

and it's the only proper and safe way to call such a function, while all other variants lack security and, often, readability.

Community
  • 1
  • 1
Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
2

This doesn't completely avoid the array but dispenses with it in one line.

function getval($query) {
    $mysqli = new mysqli();
    $mysqli->connect(HOST, USER, PASS, DB);
    return $mysqli->query($query)->fetch_row()[0];
}
Tom Lucas
  • 29
  • 3
-1

Try something like this:

$last = $mysqli->query("SELECT max(id) as last FROM table")->fetch_object()->last;

Cheers

Mick
  • 23
  • 1
  • 1
    This assumes that the scalar being returned has a known field name. This is not consistent with OP's code, which passes in ANY query (that is expected to return a single value; a "scalar" query). It might not even be a query of a record field - it could be returning a count, or even a system variable. – ToolmakerSteve Aug 03 '16 at 03:53