简体   繁体   English

为什么我的 PHP 代码从 MySQL 查询返回不正确的结果?

[英]Why is my PHP code returning incorrect results from a MySQL query?

  • FreeBSD 11.2-RELEASE FreeBSD 11.2-发布
  • Apache 2.4.43 Apache 2.4.43
  • PHP 7.4.4 PHP 7.4.4
  • MySQL 5.7.29 MySQL 5.7.29

The application I'm writing code in (OpensourcePOS) uses the CodeIgniter framework (3.1.11), and I noticed it giving me incorrect query results using the CI QueryBuilder, so I handwrote the query bypassing CI altogether but even then the results are not correct.我在(OpensourcePOS)中编写代码的应用程序使用 CodeIgniter 框架(3.1.11),我注意到它使用 CI QueryBuilder 给了我不正确的查询结果,所以我完全绕过 CI 手写了查询,但即使那样结果也不是正确的。

This MySQL query run from phpMyAdmin and the CLI returns proper results for 'category' (VARCHAR(255))此 MySQL 查询从 phpMyAdmin 运行,CLI 返回“类别”的正确结果 (VARCHAR(255))

SELECT * FROM ospos_items items
LEFT JOIN ospos_suppliers suppliers
ON suppliers.person_id = items.supplier_id
JOIN ospos_item_quantities qty
ON qty.item_id = items.item_id
WHERE items.deleted = 0
ORDER BY items.name ASC
LIMIT 1 OFFSET 0

the field 'category' is reported as 'Books' like it's supposed to be. “类别”字段被报告为“书籍”,就像它应该的那样。 The problem is that, I wasn't seeing the data I was expecting for 'Category' in the context of my application, So I ran the following debug code:问题是,我没有在我的应用程序上下文中看到我期望的“类别”数据,所以我运行了以下调试代码:

public function get_all($stock_location_id = -1, $rows = 0, $limit_from = 0)
{
    $this->db->from('items');
    $this->db->join('suppliers', 'suppliers.person_id = items.supplier_id', 'left');

    if($stock_location_id > -1)
    {
        $this->db->join('item_quantities', 'item_quantities.item_id = items.item_id');
        $this->db->where('location_id', $stock_location_id);
    }

    $this->db->where('items.deleted', 0);

    $this->db->order_by('items.name', 'asc');

    if($rows > 0)
    {
        $this->db->limit($rows, $limit_from);
    }

    $result_items = $this->db->get();

//DEBUG CODE
ob_start();
var_dump($result_items->result_array());
$res = ob_get_clean();
log_message('Error',"get_all results: $res");
//END DEBUG CODE
    return $result_items;
}

Gives me the following results.给我以下结果。 You can see that 'category' has a value 0. If there is no supplier_id (INT(11)), then 'category' shows up as null.您可以看到“类别”的值为 0。如果没有供应商 ID (INT(11)),则“类别”显示为 null。

ERROR - 2020-04-10 16:21:34 --> get_all results: <pre class='xdebug-var-dump' dir='ltr'>
<small>/usr/local/www/public_html/pos_clcdesq/application/models/Item.php:278:</small>
<b>array</b> <i>(size=1)</i>
  0 <font color='#888a85'>=&gt;</font> 
    <b>array</b> <i>(size=26)</i>
      ...
      'category' <font color='#888a85'>=&gt;</font> <small>string</small> <font color='#cc0000'>'0'</font> <i>(length=1)</i>
      'supplier_id' <font color='#888a85'>=&gt;</font> <small>string</small> <font color='#cc0000'>'362'</font> <i>(length=3)</i>
      ...
</pre>

If I comment out $this->db->join('suppliers', 'suppliers.person_id = items.supplier_id', 'left');如果我注释掉$this->db->join('suppliers', 'suppliers.person_id = items.supplier_id', 'left'); the result is correct, but of course missing the data brought in by the left join on the suppliers database (which is needed).结果是正确的,但当然缺少供应商数据库中左连接带来的数据(这是必需的)。 So naturally, I thought this was a CI Querybuilder bug so I added in a 2nd query to give me a basic select of everything in the items table that matches my ID所以很自然,我认为这是一个 CI Querybuilder 错误,所以我在第二个查询中添加了一个基本的 select 项目表中与我的 ID 匹配的所有内容

$query = $this->db->get_where('items',array('item_id'=>12203));
ob_start();
var_dump($query->result_array());
$res2 = ob_get_clean();
log_message('Error',"Custom query results: $res2");

and that result is correct, but doesn't give me the joins that I needed.这个结果是正确的,但没有给我我需要的连接。

ERROR - 2020-04-10 16:21:34 --> Custom query results: <pre class='xdebug-var-dump' dir='ltr'>
<small>/usr/local/www/public_html/pos_clcdesq/application/models/Item.php:284:</small>
<b>array</b> <i>(size=1)</i>
  0 <font color='#888a85'>=&gt;</font> 
    <b>array</b> <i>(size=21)</i>
      ...
      'category' <font color='#888a85'>=&gt;</font> <small>string</small> <font color='#cc0000'>'Books'</font> <i>(length=5)</i>
      'supplier_id' <font color='#888a85'>=&gt;</font> <small>string</small> <font color='#cc0000'>'362'</font> <i>(length=3)</i>
      ...
</pre>

From there I skipped CI QueryBuilder and wrote the query out, but still using the CI framework to handle the connection.从那里我跳过 CI QueryBuilder 并写出查询,但仍然使用 CI 框架来处理连接。

$query2 = $this->db->query("SELECT * FROM `ospos_items` items LEFT JOIN `ospos_suppliers` suppliers ON suppliers.person_id = items.supplier_id JOIN ospos_item_quantities qty ON qty.item_id = items.item_id WHERE items.deleted = 0 ORDER BY items.name ASC LIMIT 1 OFFSET 0");
ob_start();
var_dump($query2->result_array());
$res3 = ob_get_clean();
log_message('Error',"HANDWRITTEN query results: $res3");

... and I got the same incorrect data for 'category' ...我得到了同样不正确的“类别”数据

ERROR - 2020-04-10 16:21:34 --> HANDWRITTEN query results: <pre class='xdebug-var-dump' dir='ltr'>
<small>/usr/local/www/public_html/pos_clcdesq/application/models/Item.php:290:</small>
<b>array</b> <i>(size=1)</i>
  0 <font color='#888a85'>=&gt;</font> 
    <b>array</b> <i>(size=28)</i>
      ...
      'category' <font color='#888a85'>=&gt;</font> <small>string</small> <font color='#cc0000'>'0'</font> <i>(length=1)</i>
      'supplier_id' <font color='#888a85'>=&gt;</font> <small>string</small> <font color='#cc0000'>'362'</font> <i>(length=3)</i>
      ...
</pre>

So I thought, for sure this is a CI bug, I bypassed the CI framework altogether and wrote the query out by hand, using PHP to handle everything所以我想,确定这是一个 CI 错误,我完全绕过了 CI 框架并手动编写了查询,使用 PHP 来处理所有事情

$username = "[REDACTED]";
$password = "[REDACTED]";
$database = "[REDACTED]";
$mysqli = new mysqli("localhost", $username, $password, $database);
$query3="SELECT * FROM `ospos_items` items LEFT JOIN `ospos_suppliers` suppliers ON suppliers.person_id = items.supplier_id JOIN ospos_item_quantities qty ON qty.item_id = items.item_id WHERE items.deleted = 0 ORDER BY items.name ASC LIMIT 1 OFFSET 0";
$result3 = $mysqli->query("$query3");
$mysqli->close();
ob_start();
var_dump($result3->fetch_assoc());
$res4 = ob_get_clean();
log_message('Error',"noCI query results: $res4");

annnndd... same incorrect 'category' data: annnndd ...同样不正确的“类别”数据:

ERROR - 2020-04-10 16:21:34 --> noCI query results: <pre class='xdebug-var-dump' dir='ltr'>
<small>/usr/local/www/public_html/pos_clcdesq/application/models/Item.php:302:</small>
<b>array</b> <i>(size=28)</i>
  ...
  'category' <font color='#888a85'>=&gt;</font> <small>string</small> <font color='#cc0000'>'0'</font> <i>(length=1)</i>
  'supplier_id' <font color='#888a85'>=&gt;</font> <small>string</small> <font color='#cc0000'>'362'</font> <i>(length=3)</i>
  ...
</pre>

Does anyone have any idea why the query in phpMyAdmin and CLI works, the query without the left join on suppliers works from my code, but adding in the left join doesn't work in straight PHP or CI?有谁知道为什么 phpMyAdmin 和 CLI 中的查询有效,供应商上没有左连接的查询在我的代码中有效,但添加左连接在直接 PHP 或 CI 中不起作用?

You have this query:你有这个查询:

SELECT * FROM ospos_items items
LEFT JOIN ospos_suppliers suppliers
ON suppliers.person_id = items.supplier_id
JOIN ospos_item_quantities qty
ON qty.item_id = items.item_id
WHERE items.deleted = 0
ORDER BY items.name ASC
LIMIT 1 OFFSET 0

Based on your comment you retrieve two columns that have Category in your PHPMyAdmin:根据您的评论,您检索到 PHPMyAdmin 中具有类别的两列:

Instead of using * you should use aliases in your SQL and define what columns you want included.而不是使用 * 您应该在 SQL 中使用别名并定义要包含的列。

Something like: (I don't know where your categories are included but I hope you understand the concept)类似的东西:(我不知道你的类别包括在哪里,但我希望你理解这个概念)

SELECT items.category as category1, suppliers.category as category2, {other columns}
FROM ospos_items items
LEFT JOIN ospos_suppliers suppliers
ON suppliers.person_id = items.supplier_id
JOIN ospos_item_quantities qty
ON qty.item_id = items.item_id
WHERE items.deleted = 0
ORDER BY items.name ASC
LIMIT 1 OFFSET 0

Then when you fetch values in your code, you get category1 (items category) or category2 (suppliers category).然后,当您在代码中获取值时,您将获得 category1(项目类别)或 category2(供应商类别)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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