使用从数据库查询返回的 stdClass 数据对象时,特别是
$object = mysql_fetch_object($result)
如果在名称中有“.”的字段中遇到赋值问题。
例如:`user.id`
要补救这种情况,可以在赋值期间使用大括号和单引号。
代替
$myObject->user_id = $object->user.id;
使用
$myObject->user_id = $object->{'user.id'};
(PHP 4,PHP 5)
mysql_fetch_object —— 获取一个结果行作为对象
此扩展在 PHP 5.5.0 中已弃用,并在 PHP 7.0.0 中移除。取而代之的是,应使用 MySQLi 或 PDO_MySQL 扩展。另请参阅 MySQL:选择 API 指南。此函数的备选方案包括:
返回一个对象,其属性对应于已获取的行,并向前移动内部数据指针。
result
正在评估的结果 资源。此结果来自调用 mysql_query()。
class_name
要实例化的类的名称,设置其属性并返回它。如果未指定,则返回 stdClass 对象。
params
传递给 class_name
对象构造函数的 数组 参数(可选)。
示例 #1 mysql_fetch_object() 示例
<?php
mysql_connect("hostname", "user", "password");
mysql_select_db("mydb");
$result = mysql_query("select * from mytable");
while ($row = mysql_fetch_object($result)) {
echo $row->user_id;
echo $row->fullname;
}
mysql_free_result($result);
?>
示例 #2 mysql_fetch_object() 示例
<?php
class foo {
public $name;
}
mysql_connect("hostname", "user", "password");
mysql_select_db("mydb");
$result = mysql_query("select name from mytable limit 1");
$obj = mysql_fetch_object($result, 'foo');
var_dump($obj);
?>
备注: 性能
就速度而言,此函数与 mysql_fetch_array() 相同,且几乎与 mysql_fetch_row() 一样快(两者的差异可以忽略不计)。
备注:
mysql_fetch_object() 类似于 mysql_fetch_array(),不同之处在于它返回的是对象,而不是数组。这意味着您只能按字段名访问数据,而不能通过偏移量进行访问(数字是非法的属性名)。
注意:此函数返回的字段名称区分大小写。
注意:此函数会将 NULL 字段设置为 PHP
null
值。
使用从数据库查询返回的 stdClass 数据对象时,特别是
$object = mysql_fetch_object($result)
如果在名称中有“.”的字段中遇到赋值问题。
例如:`user.id`
要补救这种情况,可以在赋值期间使用大括号和单引号。
代替
$myObject->user_id = $object->user.id;
使用
$myObject->user_id = $object->{'user.id'};
如果你正在使用 mysql_fetch_object 并指定类 - 在执行构造函数之前将会设置属性。这通常不是问题,但如果你的属性是通过 __set() 魔术方法设置的并且必须首先执行构造函数逻辑,则可能导致一些主要问题。
从 PHP 5.2.1 开始,这个函数似乎不喜欢返回列名为空的查询,例如
select '' from `table`
PHP 退出,并且 mysql_error() 没有返回错误。
计时上的巨大差异可能是由数据库缓存问题引起的。如果 mysql_fetch_object() 是要使用的第一个函数,则缓存为空,但是随后的调用会从查询缓存中获取结果。
回复 rodolphe dot bodeau at free dot fr
mysql_fetch_object 函数还有另外两个可以使用的参数。
正如手册所说
mysql_fetch_object( $resource, $class_name, $params ) )
$class_name 和 $params 是可选的。
因此,如果你想在一个类中获取一行,你可以
1) 定义你的 Test 类并使用该方法和其他一些内容。
2) 执行查询
3) 调用
$Object = mysql_fetch_object( $Resource, "Test" );
所以,你可以用 $Object 来调用方法
注意你在方法中编写的代码方式:在这种情况下,使用类是为了集中化代码,而不是
真正安全,因为你可以获得附加信息
(例如,对于连接查询)却没有方法可以访问它们。
所以,类需要获取并设置一种通用的方法。
(如需了解更多信息,请参阅 O'Rielly 的 PHP 5 手册中有关如何使用通用获取和设置方法的内容)
这个小程序存储了 mysql_fetch_object 结果的内容到一个对象中,其中使用 MySQL 请求字段名作为对象参数
<?php
function FetchRequestInObject(&$obj, $req)
{
$ReqVars = get_object_vars($req);
foreach ($ReqVars as $ReqName => $ReqValue)
{
if (property_exists($obj, $ReqName))
{
$obj->$ReqName = $ReqValue;
}
}
}
?>
请记住,mysql_fetch_object 区分大小写,因此请注意你的对象属性。如有必要,可以在你的 SQL 请求中使用关键字 “AS” 来更改字段名。
注意 mysql_fetch_object() 会将所有值作为字符串返回。
如果你尝试执行
<?
$p = mysql_fetch_object($some_sql);
// 然后尝试执行类似以下操作
$money = $p->dollars + $p->cents;
?>
你可能会遇到 “不支持的操作数类型”
所以,始终将它们都强制转换为 (int) 's!!
<?php
类 Test {
公共 $go ;
私有 $id ;
函数 show() {
返回 "ID: {$this->id} Go: {$this->go}" ;
}
函数 __construct()
{
回显 "在 __construct() ". $this->show() ."\n" ;
$this->go = uniqid() ;
}
}
如果 (! ($res = mysql_query('从 `测试` 中选择 *', $db))) {
die('无效查询: ' . mysql_error() . "\n");
}
当($obj = mysql_fetch_object($res, 'Test') ){
回显 "在 ________ 外部 ". $obj->show() ."\n\n";
}
?>
此代码给予的结果
在 __construct() ID: 1 Go: first
在 ________ 外部 ID: 1 Go: 4845bd99ca2e3
在 __construct() ID: 2 Go: second
在 ________ 外部 ID: 2 Go: 4845bd99ca2fd
这意味着在使用数据填充字段后调用 __construct(),例如,它可以用于将字符串更改为整数。
这个方法提供了从数据库中获取对象的一种很好的方式。将 Federico 在 Pomi dot net 提到的,如果原生执行不工作,是因为获取的对象类型不合适,但是通过一个小类型转换,执行操作没有问题。
<?php
function ClassTypeCast(&$obj,$class_type){
if(class_exists($class_type)){
$obj = unserialize(preg_replace("/^O:[0-9]+:\\"[^\"]+\\":/i",
"O:".strlen($class_type).":\\\"".$class_type."\\":", serialize($obj)));
}
}
class Foo
{
var $foo;
var $bar;
function get_from_db()
{
mysql_connect();
mysql_select_db();
$res = mysql_query("SELECT foo,bar from my_table");
$fetched_object = mysql_fetch_object($res);
ClassTypeCast($fetched_object,"Foo");
$this = $fetched_object;
}
}
?>
这是另一种在 $this 中快速加载变量的方法,它允许在变量名上进行干预。
来自单行结果的所有列都将通过 $this->_variableName 进行加载和访问。
<?
class MyClass{
public function _load($nID) {
$Q = "SELECT * FROM myTable";
if($aTmp = RETURN_Q_ARRAY($Q)) {
$aTmp = $aTmp[0];
$aK =array_keys($aTmp);
foreach($aK as $sK) {
if(!is_numeric($sK)) $this->{"_$sK"}=$aTmp[$sK];
}
return true;
}
return false;
}
}
$o = new MyClass;
$o->_load(1);
echo $o->_id; //1
echo $o->_otherColumn; //otherColumn 值
@Jezze :这也能工作。也可以与静态方法一起使用。
<?php
class Foo
{
private $FooBar;
public function LoadFromId($Id)
{
$Result = mysql_query('SELECT * FROM foo WHERE Id = ' . $Id);
while($Row = mysql_fetch_object($Result, __CLASS__))
{
print_r($Row);
}
}
}
$Foo = new Foo;
$Foo->LoadAll();
?>
@Simon Paridon 等人关于 SQL 通过 mysql_fetch_object 获取结果到 php
任何会在数据库前端(例如 MySQL 的“查询浏览器”)中失败的查询,并且只使用 `- 标记才起作用的查询很可能在 PHP 中难以访问结果,尤其是您的列名中包含 "-" 或 " " 时。
使用 Simon Paridon 的示例:无法执行如下查询
SELECT id, user-id FROM unlucky_naming
只有
SELECT id, `user-id` FROM unlucky_naming
起作用...
因此命名列时要么更明智一些(例如 user_id)
要么尝试
SELECT id, `user-id` AS user_id FROM unlucky_naming
(我尚未在 PHP 中对其进行测试,但我猜测如果您有类似“SELECT `foo name` FROM `unlucky naming 2`" 的查询,也会失败)
稍后的“amackenz at cs dot uml dot edu”提到要给 sum、count 等命名,这对初学者可能是一个好提示:使用 (my)sql 原生函数来提高您的 php 应用程序的速度并节省数据传输和处理时间
在审阅 Eskil Kvalnes 的评论(04-Mar-2003 11:59
在查询中使用表联接时,显然需要对所有字段命名以使其与 mysql_fetch_object() 配合正常工作。)时,我仍然有疑问,而且作为一个新手,我来这里的原因也是如此。我有一个 28 字段的表。运行了带有 LEFT JOIN 等的 SELECT *,它似乎在我的测试服务器上正常工作,没有任何问题。
在进一步阅读后,MYSQL.COM 有如下内容
* 在 WHERE 子句中不允许使用列别名,因为在执行 WHERE 子句时,列值可能尚未确定。请参阅章节 A.5.4 别名问题。
* FROM table_references 子句指明要从中检索行的表。如果您指定多个表,则您正在执行联接。有关联接语法的信息,请参阅章节 6.4.1.1 JOIN 语法。对于指定的每个表,您还可以选择指定一个别名。
了解了表和字段之间有区别,此处似乎存在一些混乱。
一些关于结果集中重复字段名的先前注释的澄清。
考虑以下关系
TABLE_A(id, name)
TABLE_B(id, name, id_A)
其中 TABLE_B.id_A 引用 TABLE_A.id。
现在,如果我们这样联接这些表:“SELECT * FROM TABLE_A, TABLE_B WHERE TABLE_A.id = TABLE_B.id_A”,则结果集如下所示:(id, name, id, name, id_A)。
此处未记录 mysql_fetch_object 在此类结果上的行为,但由于字段名重复,显然会丢失某些数据。
正如 Eskil Kvalnes 所述,通过引用字段名来避免这种情况。但是,没有必要引用大表上的所有字段,因为以下语法在 MySQL 中是合法的:“SELECT *, TABLE_A.name AS name_a, TABLE_B.name AS name_b FROM TABLE_A, TABLE_B ...”。这将生成格式如下所示的结果集:(id, name, id, name, id_A, name_a, name_b),并且您的数据已保存。万岁!
-q
小心
返回的对象将是一个新的/最新对象。
您不能使用此函数替换现有对象的某些属性,同时保留旧属性。
示例
类人物
{
var $name;
var $surname;
var $doh;
函数打印()
{
print($name." ".$surname);
}
函数 get_from_db()
{
$res=query("select name, surname from ppl where... limit 1");
$this=mysql-fetch-object($res);
}
}
这将不起作用!在执行方法 get_from_db() 时,您的旧对象将被销毁... 您在属性 $doh 中找不到任何内容,并且如果尝试调用方法 print(),它将表示该方法不存在。
我创建了一个表格,其中包含 5 列 INT 和 1000 行的随机 int。
我进行了 100 次选择
SELECT * FROM bench... (mysql_fetch_object)
查询时间:5.40725040436
获取时间:16.2730708122(平均值:1.32130565643E-5)
总时间:21.6803212166
SELECT * FROM bench... (mysql_fetch_array)
查询时间:5.37693023682
获取时间:10.3851644993(平均值:7.48886537552E-6)
总时间:15.7620947361
SELECT * FROM bench... (mysql_fetch_assoc)
查询时间:5.345921278
获取时间:10.6170959473(平均:7.64049530029E-6)
总时间:15.9630172253
“注意:性能速度方面,此函数与 mysql_fetch_array() 相同,几乎与 mysql_fetch_row() 一样快(差别微乎其微)。”
我是一只企鹅 :)
这可能更优雅一些。
$sql = “SELECT * FROM table ”;
$result = mysql_query($sql);
$data = array();
while ($row = mysql_fetch_object($result))
$data[] = $row;
这是提取一个“宽表”中所有单个字段名的整个查询的一种非常非常优雅(并且无需付费)的方式。
繁琐的提取方式
<?php
$idtable=mysql_connect("localhost","user","pwd");
mysql_select_db("table",$idtable);
$consult=mysql_query("SELECT *
FROM models
ORDER BY Serie,Year ASC");
while($row=mysql_fetch_object($consult)){
foreach($row as $name => $value){
$$name=$value;
}
echo "MODEL: ".$Model."
";
echo "SERIE: ".$Serie."
";
echo "YEAR: ".$Year."
";
echo "-------------------";
echo "
";
}
?>
Con esto conseguimos 15 nuevas variables con el mismo nombre que los campos de la tabla. Lo hemos introducido manualmente en 5 minutos. ¡Pero imagina que cada fila tiene 100 campos!
Una forma de ahorrar tiempo con el mismo resultado
<?php
$idtable=mysql_connect("localhost","user","pwd");
mysql_select_db("table",$idtable);
$consult=mysql_query("SELECT *
FROM models
ORDER BY Serie,Year ASC");
// 我们查找字段数
$numfields=mysql_num_fields($consult);
// 现在我们将字段名放到一个数组中
for($i=0;$i<$numfields;$i++){
$fieldname[$i]=mysql_field_name($consult, $i);
}
while($row=mysql_fetch_object($consult)){
// 最后,我们分配新变量
for($i=0;$i<$numfields;$i++){
$$fieldname[$i]=$row->$fieldname[$i];
}
}
?>
如果有一个类表示它自己在数据库中,则可以使用此函数来获取属性。
类 MyClass {
public $name;
public $language;
function load($id) {
$query = mysql_query("SELECT name, language FROM myTable WHERE id = $id");
$result = mysql_fetch_object($query, get_class($this));
foreach(get_object_vars($result) as $var => $value) $this->$var = $value;
}
}
$a = new MyClass();
$a->load(1);
对上一个内容的补充...
例如从数据库中获取成员
function getAllMembers () {
$query = "SELECT * FROM people ORDER BY lname";
$result = mysql_query($query);
while($member = mysql_fetch_object($result)){
$members[] = $member;
}
return $members;
}
<br><br>
不要忘记声明数组。如果你尝试在调用函数后在成员中循环,并且你没有首先声明数组,你将在页面中遇到一个可怕(太可怕了!)的丑陋错误。另外,如果你尝试在 while 条件中而不是在 while 循环中将对象添加到 members 数组中,你将在数组中生成一个额外的空空间,这会归因于最后的迭代/检查。
我发现上述代码有 BUG,没有将所有记录添加到数组中。这是我使用过的代码
$command = "SELECT * FROM table ";
$result = mysql_query($command, $link_id);
$num = mysql_num_rows($result);
$clickthru = array();
for ($i = 0; $i <= $num; $i++) {
$clickthru[$i] = array();
$clickthru[$i] = mysql_fetch_array($result);
}
Allen
这是一个允许指定类名的包装器。
function &db_fetch_object($set,$className)
{
/* 从获得普通数组开始 */
$row = mysql_fetch_assoc($set);
if ($row === null) return null;
/* 创建对象 */
$obj =& new $className();
/* 展开数组,并设置对象的实例数据 */
foreach($row as $key => $value)
{
$obj->{$key} = $value;
}
return $obj;
}
class CPerson
{
function getFullName()
{
return $this->fname . ' ' . $this->lname;
}
}
$set = mysql_query('SELECT fname,lname FROM person');
while($person =& db_fetch_object($set,'CPerson'))
{
echo $person->getFullName();
}
此函数的行为稍微有点可疑。
如果你在表中具有包含非变量名字符(如“ -”)的列,mysql_fetch_object 将向你的对象中添加“不可能的变量名”,例如
object (
[user-id] => 7
)
因为变量名无效,所以你不能使用 $obj->user-id 来正常访问此变量。不过,你可以像这样访问它
$foo = 'user-id';
echo $obj->$foo;
它将正确输出 7,而由于某种原因,var_dump($obj->user-id) 将输出 int(0)。
我在 PHP 4.4.2 中遇到了这种行为。