草庐IT

php - 我如何从mysql中获取数据以表现

coder 2023-10-12 原文

所以我想填充并显示一个HTML表,它有两列宽。但是,不管我做什么,我的数据总是粘在一起的。
问题是,我真的想把所有的数据放到一个表中,按起始字母排序。
这是我的代码:

<?php include_once 'Database/dbh.php'; ?>

<!DOCTYPE html>
<html>
    <body>
        <?php
        $fetch = "SELECT DISTINCT Kategori, LEFT(Kategori, 1) AS Letter FROM kategorier ORDER BY Kategori;";
        $result = mysqli_query($conn, $fetch);
        $resultCheck = mysqli_num_rows($result);

        if ($resultCheck > 0) {
            while ($row = mysqli_fetch_assoc($result)) {
                if (!isset($lastLetter) || $lastLetter != $row['Letter']) {
                    $lastLetter = $row['Letter'];
                    echo "<h2>", $row['Letter'], "</h2>";
                }
                echo "<table><tr><td>" . $row['Kategori'] . "</td></tr></table>";
            }
        }
        ?>      
    </body>
</html>

这是一张现在的照片:

下面是我想要的样子:

最佳答案

很抱歉让你失望,但解决办法比你想象的要复杂得多。正如我所见,“艾恩伯已经建议了。所以,如果他写了一个答案,那么首先考虑他的答案是公平的。
建议
关于关注点的分离:
现在让我首先说,为了将来,你应该熟悉Separation of Concerns原则。简单地说,以你的代码为例:总是将涉及数据库访问的代码(用于获取数据、更新等)与显示数据的代码(例如页面的html部分)分开。
这意味着,如果需要从数据库中获取数据,请在网页顶部执行此操作,并将其保存在数组中。然后只需在网页的html部分中使用这些数组,而不是像mysqli_querymysqli_fetch_assoc等与db相关的函数。为了清楚起见,请参阅我提供的代码的html部分(“index.php”)。
这种方法的一大优点是,您可以将整个php代码从页面顶部移动到php函数或类方法中。然后数组将只包含调用这些函数/方法所产生的数据。
以上所有陈述的要点是什么?随意处理php代码和网页顶部的数据,并将结果保存在php数组中。最后,数组应该具有这样的结构,这样网页的html部分的工作将非常简单:只读取和显示数组元素。
所以不要把html代码和db相关的代码混合在一起。如果你这样做了,那么代码就太难维护了。
关于从php打印客户端代码:
您应该记住的另一个重要约定是,不要使用php代码打印任何客户端代码。例如,不要使用像echo "<table><tr><td>"...这样的语句。在这种情况下,只需将要显示的内容保存到变量中,并根据需要将其显示在网页的html部分。
关于准备好的陈述:
如果需要执行带参数的sql语句,则使用prepared statements(在本例中不使用echo)。他们会保护你的代码不被最终的sql injections。为了完成,在这个答案的末尾,我发布了一个使用准备好的语句而不是mysqli::query的示例。
问题的解决方案:
步骤:
关于我准备的解决方案,它包括四个步骤:
从数据库中获取数据并将其保存到数组中(index.php)。
首先,创建第二个数组(mysqli::query)。然后遍历$data并以这种方式将其项保存到$formattedData中,以便它们可以很容易地显示在所选的html结构中(字母$data,类别$formattedData)。
遍历div并在每个字母的最后一个category行中为每个缺少的category追加一个category name为table的项。抱歉,我在这里写了一句话,但是,如果您阅读我代码中的注释,您一定会更好地理解我的意思。
通过遍历$formattedData并读取其值,在页面的html部分显示数据。
当然,您可以根据需要优化php代码和/或将其分发到两个三个函数中。然后您可以调用它们并将它们的返回值赋给null$formattedData变量。
注:
如果您使用我的连接代码,不要忘记用您的数据库凭据替换我的数据库凭据。
index.php索引

<?php
require 'Database/dbh.php';

$sql = 'SELECT
            DISTINCT Kategori,
            LEFT(Kategori, 1) AS Letter
        FROM kategorier
        ORDER BY Kategori';

$result = mysqli_query($conn, $sql);

/*
 * Fetch all data at once, into an array like this:
 *
 *  Array
 *  (
 *      [0] => Array
 *          (
 *              [Kategori] => Artiskok
 *              [Letter] => A
 *          )
 *
 *      [1] => Array
 *          (
 *              [Kategori] => Asiatisk
 *              [Letter] => A
 *          )
 *
 *      [2] => Array
 *          (
 *              [Kategori] => Burger
 *              [Letter] => B
 *          )
 *
 *      [...] => [...]
 *
 *  )
 */
$data = mysqli_fetch_all($result, MYSQLI_ASSOC);

/*
 * Free the memory associated with the result. You should
 * always free your result when it is not needed anymore.
 *
 * @link http://php.net/manual/en/mysqli-result.free.php
 */
mysqli_free_result($result);

/*
 * Close the previously opened database connection. Not really needed because
 * the PHP engine closes the connection anyway when the PHP script is finished.
 *
 * @link http://php.net/manual/en/mysqli.close.php
 */
mysqli_close($conn);

/*
 * Iterate through the fetched data and save it into a new array, with a structure suited for the
 * required HTML display. To each letter, a list of category rows is assigned. The new array will
 * look like this, when the maximal number of categories per category row is 2:
 *
 *  Array
 *  (
 *      [A] => Array
 *          (
 *              [0] => Array
 *                  (
 *                      [0] => Aoiuoiiiu
 *                      [1] => Aqewroiuoiiu
 *                  )
 *
 *              [1] => Array
 *                  (
 *                      [0] => Artiskok
 *                      [1] => Asiatisk
 *                  )
 *
 *              [2] => Array
 *                  (
 *                      [0] => Azkajhsdfjkh
 *                  )
 *
 *          )
 *
 *      [B] => Array
 *          (
 *              [0] => Array
 *                  (
 *                      [0] => Bhaskdfhjkh
 *                      [1] => Biuzutt
 *                  )
 *
 *              [1] => Array
 *                  (
 *                      [0] => Burger
 *                  )
 *
 *          )
 *
 *      [...] => [...]
 *
 *  )
 */
$formattedData = [];

// The maximal number of categories per each category row.
$maximalNumberOfCategoriesPerCategoryRow = 2;

// The number of categories per current category row.
$numberOfCategoriesPerCurrentCategoryRow = 0;

// The index of a category row in the list of all category rows assigned to a letter.
$indexOfCurrentCategoryRow = 0;

foreach ($data as $item) {
    $letter = $item['Letter'];
    $category = $item['Kategori'];

    if (!array_key_exists($letter, $formattedData)) {
        /*
         * Assign an item with the current letter as key and an array as value.
         * The array holds all category rows for the current letter.
         */
        $formattedData[$letter] = [];

        // Reset.
        $indexOfCurrentCategoryRow = 0;

        // Reset.
        $numberOfCategoriesPerCurrentCategoryRow = 0;
    }

    // Append the current category to the current category row for the current letter.
    $formattedData[$letter][$indexOfCurrentCategoryRow][] = $category;

    // Increment.
    $numberOfCategoriesPerCurrentCategoryRow++;

    /*
     * If the maximal number of categories per category row is reached...
     *
     * @see "Modulo" operator at https://secure.php.net/manual/en/language.operators.arithmetic.php
     */
    if (
            $numberOfCategoriesPerCurrentCategoryRow %
            $maximalNumberOfCategoriesPerCategoryRow === 0
    ) {
        // Reset.
        $numberOfCategoriesPerCurrentCategoryRow = 0;

        // Increment.
        $indexOfCurrentCategoryRow++;
    }
}

/*
 * Append an item with "null" as category for each missing category in the last
 * category row of each letter. The array holding the formatted data will look
 * like this, when the maximal number of categories per category row is 2:
 *
 *  Array
 *  (
 *      [A] => Array
 *          (
 *              [...] => [...]
 *
 *              [2] => Array
 *                  (
 *                      [0] => Azkajhsdfjkh
 *                      [1] => null
 *                  )
 *
 *          )
 *
 *      [B] => Array
 *          (
 *              [...] => [...]
 *
 *              [1] => Array
 *                  (
 *                      [0] => Burger
 *                      [1] => null
 *                  )
 *
 *          )
 *
 *      [...] => [...]
 *
 *  )
 */
foreach ($formattedData as $letter => $categoryRows) {
    $lastCategoryRow = end($categoryRows);
    $lastCategoryRowKey = key($categoryRows);

    $numberOfCategoriesPerLastCategoryRow = count($lastCategoryRow);

    $numberOfMissingCategoriesInLastCategoryRow = $maximalNumberOfCategoriesPerCategoryRow -
            $numberOfCategoriesPerLastCategoryRow;

    for ($i = 0; $i < $numberOfMissingCategoriesInLastCategoryRow; $i++) {
        // Append an item with "null" as category.
        $formattedData[$letter][$lastCategoryRowKey][] = null;
    }
}

//=====================================================================================
//@todo Just for testing: uncomment the next two lines to display the arrays on screen.
//=====================================================================================
//echo '<pre>' . print_r($data, TRUE) . '</pre>';
//echo '<pre>' . print_r($formattedData, TRUE) . '</pre>';
//=====================================================================================
?>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
        <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes" />
        <meta charset="UTF-8" />
        <!-- The above 3 meta tags must come first in the head -->

        <title>Demo</title>

        <link href="custom.css" type="text/css" rel="stylesheet">
    </head>
    <body>

        <h3>
            Demo: Print a list of categories per category letter, on multiple columns.
        </h3>

        <?php
        if ($formattedData) { /* Data exists */
            foreach ($formattedData as $letter => $categoryRows) {
                ?>
                <div class="categories-container">
                    <div class="letter">
                        <?php echo $letter; ?>
                    </div>
                    <table class="categories">
                        <?php
                        foreach ($categoryRows as $categoryRow) {
                            ?>
                            <tr>
                                <?php
                                foreach ($categoryRow as $category) {
                                    ?>
                                    <td>
                                        <?php echo $category; ?>
                                    </td>
                                    <?php
                                }
                                ?>
                            </tr>
                            <?php
                        }
                        ?>
                    </table>
                </div>
                <?php
            }
        } else { /* No data */
            ?>
            <p class="no-data">
                No data found
            </p>
            <?php
        }
        ?>

    </body>
</html>

自定义.css
body {
    margin: 0;
    padding: 20px;
    color: #333;
}

a {
    text-decoration: none;
}

.categories-container {
    margin-bottom: 10px;
}

.letter {
    padding: 10px;
    text-align: left;
    font-weight: 700;
    background-color: #a0c3e5;
}

.categories {
    width: 100%;
    border-spacing: 1px;
    border-collapse: separate;
}

.categories td {
    width: 50%;
    padding: 10px;
    background-color: #f4f4f4;
}

.no-data {
    padding: 10px;
    background-color: #f4f4f4;
}

数据库/dbh.php
<?php

/*
 * This page contains the code for creating a mysqli connection instance.
 */

// Db configs.
define('HOST', 'localhost');
define('PORT', 3306);
define('DATABASE', 'tests');
define('USERNAME', 'root');
define('PASSWORD', 'root');

// Error reporting.
error_reporting(E_ALL);
ini_set('display_errors', 1); /* SET IT TO 0 ON A LIVE SERVER! */

/*
 * Enable internal report functions. This enables the exception handling,
 * e.g. mysqli will not throw PHP warnings anymore, but mysqli exceptions
 * (mysqli_sql_exception).
 *
 * MYSQLI_REPORT_ERROR: Report errors from mysqli function calls.
 * MYSQLI_REPORT_STRICT: Throw a mysqli_sql_exception for errors instead of warnings.
 *
 * @link http://php.net/manual/en/class.mysqli-driver.php
 * @link http://php.net/manual/en/mysqli-driver.report-mode.php
 * @link http://php.net/manual/en/mysqli.constants.php
 */
$mysqliDriver = new mysqli_driver();
$mysqliDriver->report_mode = (MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

// Create a new db connection.
$conn = mysqli_connect(HOST, USERNAME, PASSWORD, DATABASE, PORT);

测试用数据
CREATE TABLE `kategorier` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `Kategori` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `kategorier` (`id`, `Kategori`)
VALUES
    (1,'Artiskok'),
    (2,'Asiatisk'),
    (3,'Burger'),
    (4,'Pizza'),
    (5,'Asiatisk'),
    (6,'Artiskok'),
    (7,'Artiskok'),
    (8,'Durum'),
    (9,'Durum'),
    (10,'Pizza'),
    (11,'Chinaboks'),
    (12,'Azkajhsdfjkh'),
    (13,'Aoiuoiiiu'),
    (14,'Aqewroiuoiiu'),
    (15,'Bhaskdfhjkh'),
    (16,'Biuzutt');

结果

附加内容:
这是一个如何使用准备好的语句而不是$data获取数据的示例。注意,我只把数据获取代码放在这里。其余代码与上面$formattedData页的omolog部分相同,后者使用mysqli::query
index.php索引
<?php

require 'Database/dbh.php';

/*
 * Save the values, with which the database data will be filtered, into variables.
 * These values will replace the parameter markers in the sql statement.
 * They can come, for example, from a POST request of a submitted form.
 */
$letterParam1 = 'A';
$letterParam2 = 'C';
$letterParam3 = 'P';

/*
 * The SQL statement to be prepared. Notice the so-called markers, e.g. the "?" signs. They
 * will be replaced later with the corresponding values when using mysqli_stmt::bind_param.
 *
 * @link http://php.net/manual/en/mysqli.prepare.php
 */
$sql = 'SELECT
            DISTINCT Kategori,
            LEFT(Kategori, 1) AS Letter
        FROM kategorier
        WHERE
            LEFT(Kategori, 1) = ?
            OR LEFT(Kategori, 1) = ?
            OR LEFT(Kategori, 1) = ?
        ORDER BY Kategori';

/*
 * Prepare the SQL statement for execution - ONLY ONCE.
 *
 * @link http://php.net/manual/en/mysqli.prepare.php
 */
$statement = mysqli_prepare($conn, $sql);

/*
 * Bind variables for the parameter markers (?) in the SQL statement that was passed to prepare().
 * The first argument of bind_param() is a string that contains one or more characters which
 * specify the types for the corresponding bind variables.
 *
 * @link http://php.net/manual/en/mysqli-stmt.bind-param.php
 */
mysqli_stmt_bind_param($statement, 'sss'
        , $letterParam1
        , $letterParam2
        , $letterParam3
);

/*
 * Execute the prepared SQL statement. When executed any parameter markers
 * which exist will automatically be replaced with the appropriate data.
 *
 * @link http://php.net/manual/en/mysqli-stmt.execute.php
 */
mysqli_stmt_execute($statement);

/*
 * Get the result set from the prepared statement.
 *
 * NOTA BENE:
 *
 * Available only with mysqlnd ("MySQL Native Driver")! If this is not installed, then
 * uncomment "extension=php_mysqli_mysqlnd.dll" in PHP config file (php.ini) and restart
 * web server (I assume Apache) and mysql service. Or use the following functions instead:
 * mysqli_stmt::store_result + mysqli_stmt::bind_result + mysqli_stmt::fetch.
 *
 * @link http://php.net/manual/en/mysqli-stmt.get-result.php
 * @link https://stackoverflow.com/questions/8321096/call-to-undefined-method-mysqli-stmtget-result
 */
$result = mysqli_stmt_get_result($statement);

/*
 * Fetch all data at once, into an array like this:
 *
 *  Array
 *  (
 *      [0] => Array
 *          (
 *              [Kategori] => Artiskok
 *              [Letter] => A
 *          )
 *
 *      [1] => Array
 *          (
 *              [Kategori] => Asiatisk
 *              [Letter] => A
 *          )
 *
 *      [2] => Array
 *          (
 *              [Kategori] => Burger
 *              [Letter] => B
 *          )
 *
 *      [...] => [...]
 *
 *  )
 */
$data = mysqli_fetch_all($result, MYSQLI_ASSOC);

/*
 * Free the memory associated with the result. You should
 * always free your result when it is not needed anymore.
 *
 * @link http://php.net/manual/en/mysqli-result.free.php
 */
mysqli_free_result($result);

/*
 * Close the prepared statement. It also deallocates the statement handle.
 * If the statement has pending or unread results, it cancels them
 * so that the next query can be executed.
 *
 * @link http://php.net/manual/en/mysqli-stmt.close.php
 */
mysqli_stmt_close($statement);

/*
 * Close the previously opened database connection. Not really needed because
 * the PHP engine closes the connection anyway when the PHP script is finished.
 *
 * @link http://php.net/manual/en/mysqli.close.php
 */
mysqli_close($conn);

/*
 * ---------------------------------------------------------------------------------------------
 * The rest of the page is identical with the omolog part of index.php, which uses mysqli::query
 * ---------------------------------------------------------------------------------------------
 */

// ...

关于php - 我如何从mysql中获取数据以表现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52670598/

有关php - 我如何从mysql中获取数据以表现的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  4. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  5. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  6. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  7. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  8. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  9. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  10. ruby - 如何使用文字标量样式在 YAML 中转储字符串? - 2

    我有一大串格式化数据(例如JSON),我想使用Psychinruby​​同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解

随机推荐