Цикл mysql_fetch_array - зачем он нужен?
Код:
$query = "SELECT Name, CountryCode FROM City ORDER by ID DESC LIMIT 50,5";
$result = mysqli_query($link, $query)
/* fetch associative array */
//!!!!!!!
while ($row = mysqli_fetch_assoc($result)) {
printf ("%s (%s)\n", $row["Name"], $row["CountryCode"]);
}
//!!!!!!
/* free result set */
mysqli_free_result($result);
$result = mysqli_query($link, $query)
/* fetch associative array */
//!!!!!!!
while ($row = mysqli_fetch_assoc($result)) {
printf ("%s (%s)\n", $row["Name"], $row["CountryCode"]);
}
//!!!!!!
/* free result set */
mysqli_free_result($result);
Код:
$result = mysqli_query($link, $query)
Вся логика цикла понятна - при присвоении функции $row = mysql_fetch_array($result) производится чтение и увеличение внутри $result на единицу после каждого обращения/присвоения. И каждый раз в цикле переменная $row "затирается".
Но зачем реализовать цикл, если в $result уже сразу вся выборка из базы данных есть и её просто можно было бы присвоить двумерному массиву?
Например:
Код:
$arr2d = array(
array()
);
$query = "SELECT Name, CountryCode FROM City WHERE CountryCode = 'NLD' ORDER BY ID DESC"
$result = mysql_query($query);
$arr2d = mysql_fetch_table($result)
echo $arr2d[0]['Name']; // должно было бы вывести "Alkmaar"
array()
);
$query = "SELECT Name, CountryCode FROM City WHERE CountryCode = 'NLD' ORDER BY ID DESC"
$result = mysql_query($query);
$arr2d = mysql_fetch_table($result)
echo $arr2d[0]['Name']; // должно было бы вывести "Alkmaar"
На мой взгляд, она была бы очень удобна.
Как вы считаете?
Или такая функция есть, но я о ней не знаю?
http://www.php.net/manual/en/function.mysql-result.php
Это довольно низкий уровень взаимодействия с базой, но он же самый быстрый.
Цитата: int
http://www.php.net/manual/en/function.mysql-result.php
Эта функция позволяет обратиться сразу к элементу по порядковому номеру (без цикла), но не извлекает сразу всю выборку в массив. Немного не то. Т.е. чтобы извлечь всю выборку, мне опять-таки надо организовать цикл.
Я не ПХП шник, но эта ваша "переменная" ($result = mysql_query($query) - вовсе даже похожа на "датаридер" . А датаридер не содержит всех записей а читает их с сервера по команде, одну за другой и только в одном направлении.
Это довольно низкий уровень взаимодействия с базой, но он же самый быстрый.
Это довольно низкий уровень взаимодействия с базой, но он же самый быстрый.
Т.е., другими словами, хотя в коде явно в $result переменную заносится значение один раз:
Код:
$result = mysqli_query($link, $query)
Код:
$row = mysqli_fetch_assoc($result)
Если так, то этот код должен быть нерабочим:
Код:
<?php
$link = mysqli_connect("localhost","root","root");
mysqli_select_db($link,"world");
$sql = "SELECT * FROM country WHERE Continent = 'Europe'";
$res = mysqli_query($link,$sql); // здесь якобы получили только первый ряд (row)
mysqli_close($link); // здесь закрываем соединение и по идее, не можем больше взаимодействовать с базой данных
echo "<table border='1'>";
while ($row = mysqli_fetch_assoc($res)) // здесь цикл должен бы "прокрутиться" только один раз
{
echo "<tr>";
foreach($row as $key => $value)
{
echo "<td>".$value."</td>";
}
echo "</tr>";
}
echo "</table>";
?>
$link = mysqli_connect("localhost","root","root");
mysqli_select_db($link,"world");
$sql = "SELECT * FROM country WHERE Continent = 'Europe'";
$res = mysqli_query($link,$sql); // здесь якобы получили только первый ряд (row)
mysqli_close($link); // здесь закрываем соединение и по идее, не можем больше взаимодействовать с базой данных
echo "<table border='1'>";
while ($row = mysqli_fetch_assoc($res)) // здесь цикл должен бы "прокрутиться" только один раз
{
echo "<tr>";
foreach($row as $key => $value)
{
echo "<td>".$value."</td>";
}
echo "</tr>";
}
echo "</table>";
?>
Тем не менее, этот код работает. Значит, в $result появилась сразу вся выборка, не так ли?
Значит, или я не понял вашу мысль, или ваше утверждение неверно. Если я неправильно понял, пожалуйста, потрудитесь яснее описать, что имеете в виду.
Ещё это может быть баг PHP, хотя я так не думаю, так как мой код (где сначала mysqli_close($link), потом цикл) не противоречит логике (по крайней мере той, которую я описал).
Это можно узнать, если разобрать детально реализацию функций. Может быть закрыло, а может быть и проверило - что еще используется и не закрыло, а может быть и кэш какой-нибудь сработал, проверьте ваш код на миллионе записей.....
>>>>> Значит, или я не понял вашу мысль, или ваше утверждение неверно.
- это следует понимать так - " Гарри, сдается мне, что он хочет нас обидеть". :-)
Вы поняли правильно. Но я не писал что утверждаю, а только предполагаю на основании сходства.
>>>>> Ещё это может быть баг PHP, хотя я так не думаю
Вот и правильно. Не стоит искать баги в системе, которую используют миллионы. :-)
Я не пишу на PHP, но из опыта работы с другими системами - могу сказать, что если кажется, что функцию добавили зря, то это только кажется.
Без нее не обойтись, а это значит, что сам обьект, который для вас как бы очевидно что двумерный массив, на самом деле не так уж прост, и не может быть приведен к двумерному массиву автоматически.
:-)
Цитата: D129
Думаю, надо начать дискуссию. А там кто-нибудь, кто собаку съел - подтянется и скажет свое веское слово.
:-)
:-)
Вот я и собаку съел, когда почитал про PDO :)
Оказывается, всё это можно сделать, только надо использовать PDO и тогда можно забрать всю выборку одной строкой кода, без всяких циклов. Отобразить, вот, конечно, придётся с циклами (двумя, мы ведь берём двумерный массив - таблицу, матрицу).
Если кому интересно:
Код:
$host = "localhost";
$user = "root";
$pass = "root";
$dbname = "world";
try
{
$dbh = new PDO ("mysql:host=$host;dbname=$dbname",$user,$pass);
$dbh -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $e)
{
echo $e -> getMessage();
}
$data = array ( 'ccode' => 'NLD',
'population' => 130000
);
$sql = "SELECT ID, Name, Population
FROM City
WHERE CountryCode = :ccode
AND Population > :population
ORDER BY Name ASC";
$stmt = $dbh -> prepare($sql);
$stmt -> execute($data);
$stmt -> setFetchMode(PDO::FETCH_ASSOC);
$cities = $stmt-> fetchAll();
// $cities here - array of arrays, or 2-dimensional array,
// which we extracted not in a loop, but in one line of code
// view cities START
echo "<table border='1' >";
foreach ($cities as $city) // seek every row <-> city in $cities
{
echo "<tr>";
// every $city is an array itself,
// $city is 1-dimensional array, so we need to extract every column in each row <-> field in each row
foreach ($city as $field)
{
echo "<td>".$field."</td>";
}
echo "</tr>";
}
echo "</table>";
// view cities END
$stmt = null;
$dbh = null;
$user = "root";
$pass = "root";
$dbname = "world";
try
{
$dbh = new PDO ("mysql:host=$host;dbname=$dbname",$user,$pass);
$dbh -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $e)
{
echo $e -> getMessage();
}
$data = array ( 'ccode' => 'NLD',
'population' => 130000
);
$sql = "SELECT ID, Name, Population
FROM City
WHERE CountryCode = :ccode
AND Population > :population
ORDER BY Name ASC";
$stmt = $dbh -> prepare($sql);
$stmt -> execute($data);
$stmt -> setFetchMode(PDO::FETCH_ASSOC);
$cities = $stmt-> fetchAll();
// $cities here - array of arrays, or 2-dimensional array,
// which we extracted not in a loop, but in one line of code
// view cities START
echo "<table border='1' >";
foreach ($cities as $city) // seek every row <-> city in $cities
{
echo "<tr>";
// every $city is an array itself,
// $city is 1-dimensional array, so we need to extract every column in each row <-> field in each row
foreach ($city as $field)
{
echo "<td>".$field."</td>";
}
echo "</tr>";
}
echo "</table>";
// view cities END
$stmt = null;
$dbh = null;
Код:
$host = "localhost";
$user = "root";
$pass = "root";
$dbname = "world";
try
{
$dbh = new PDO ("mysql:host=$host;dbname=$dbname",$user,$pass);
$dbh -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $e)
{
echo $e -> getMessage();
}
$sql = "SELECT ID, Name, Population
FROM City
WHERE CountryCode = 'NLD'
AND Population > 130000
ORDER BY Name ASC";
$result = $dbh -> query($sql);
$result -> setFetchMode(PDO::FETCH_ASSOC);
$cities = $result -> fetchAll();
// $cities here - array of 1-dimensional arrays, or 2-dimensional array,
// which we extracted not in a loop, but in one line of code, which is to my mind more efficient
// view cities START
echo "<table border='1' >";
foreach ($cities as $city) // seek every row <-> city in $cities
{
echo "<tr>";
// every $city is an array itself,
// $city is 1-dimensional array, so we need to extract every column in each row <-> field in each row
foreach ($city as $field)
{
echo "<td>".$field."</td>";
}
echo "</tr>";
}
echo "</table>";
// view cities END
$result = null;
$dbh = null;
$user = "root";
$pass = "root";
$dbname = "world";
try
{
$dbh = new PDO ("mysql:host=$host;dbname=$dbname",$user,$pass);
$dbh -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $e)
{
echo $e -> getMessage();
}
$sql = "SELECT ID, Name, Population
FROM City
WHERE CountryCode = 'NLD'
AND Population > 130000
ORDER BY Name ASC";
$result = $dbh -> query($sql);
$result -> setFetchMode(PDO::FETCH_ASSOC);
$cities = $result -> fetchAll();
// $cities here - array of 1-dimensional arrays, or 2-dimensional array,
// which we extracted not in a loop, but in one line of code, which is to my mind more efficient
// view cities START
echo "<table border='1' >";
foreach ($cities as $city) // seek every row <-> city in $cities
{
echo "<tr>";
// every $city is an array itself,
// $city is 1-dimensional array, so we need to extract every column in each row <-> field in each row
foreach ($city as $field)
{
echo "<td>".$field."</td>";
}
echo "</tr>";
}
echo "</table>";
// view cities END
$result = null;
$dbh = null;