为该国显示世界前 5% 和 10% 的奖杯 [按百分比排名系统]

Show trophies on top 5% and 10% in the world for the country [Ranking System by Percent]

正在开发 php 游戏,所以我有一个 table "country_development_areas" 奖杯应该出现在用户国家/地区页面中。每个奖杯从 "value" 0 开始。值越大排名越高。我附上了一张带有 table 波纹管的图片:

用户国家页面上应该显示两行: - 第一行显示与 "value" 领域世界排名前 5% 的国家相对应的奖杯。 - 第二行显示与 "value" 领域世界排名前 10% 的国家相对应的奖杯。

全球排名应按 "value" 与所有国家进行比较,并显示与该国家对应的奖杯行。它也应该在 link 标题中有相应的排名,如 "Most Efficient Economies: 3,420th".

下面是我到目前为止的代码,它显示了奖杯,但它显示了所有内容,所以我不知道如何让它们按百分比排名显示。

<?php
    // Get all rows from country_development_areas table
    try {
        $stmt = $db->prepare('SELECT * FROM country_development_areas WHERE country = :idCountry ORDER BY value DESC');
        $stmt->execute(array(':idCountry' => $row_country['id']));
    } catch(PDOException $e) {
        $error[] = $e->getMessage();
    }
?>


<div id="trophycabinet">

                        <?php
                        while($row_country_development_area = $stmt->fetch(PDO::FETCH_ASSOC))  {
                        ?>

                            <a class="top5percent" href="/nation=united_states_of_america/detail=trend?censusid=<?php echo $row_country_development_area['id']; ?>" title="<?php echo $row_country_development_area['title']; ?>: 3,420th">
                                <?php echo $row_country_development_area['icon']; ?>
                            </a>

                        <?php } ?>
                        
</div>

首先,对于前 5% 的用户,用户应该会看到一行带有奖杯的信息,如下面的屏幕截图所示。这是目前剧本显示的内容,但只显示该国的所有奖杯,它不会只显示与世界相比前5%,因为我不知道该怎么做。

其次应该是第二行,就像前 10% 一样显示奖杯行。

这是完整的代码,包括排名位置。您可以根据需要添加任意数量的热门类型。

  • 不要在 id 列中使用 id = 0!
  • 不在表格中放置图标 html。只将图标名称放在 icon 列中,例如 "hand-peace-o".
  • 有关正确的准备语句+验证+异常处理,请参阅(如果您想使用class,还有编辑部分)。
  • 我只使用了 icon 列中的图标名称。
  • 您应该在 catch 块中使用我的建议。因为异常通常是一种错误类型,在此之后您不想继续任何程序步骤,而只想在屏幕上显示错误消息并退出。
  • 尽量避免在任何编程语言的代码中使用 while 语句。除了也许在那里,他们在哪里……不可避免。例如。如果它们有很好的文档记录,例如,在 PHP 文档网站上针对不同的数据访问功能,并且确实需要,那么就使用它们。但要小心,因为它们会导致无限循环,使您的服务器完全超载。
  • 将 PHP 数据访问部分与 HTML 部分分开。如果您需要数据,请在 PHP 数组和 PHP 页面的上部获取所有数据。在 PHP 页面的 HTML 部分,只需遍历这些数组。因此,简而言之,不要将 PHP 数据访问代码与 HTML 代码混合使用。赞:PHP 页面的 HTML 部分没有 fetch()

祝你好运。

PHP代码:

<?php
// Get all rows from country_development_areas table
try {
    // Read from HTTP POST.
    $country = 1;

    /*
     * Array containing the top types (top 5%, top 10%, top 20%, etc) as keys and
     * the areas lists for each top as values.
     */
    $tops = array(
        5 => array(),
        10 => array(),
        20 => array(),
        80 => array(),
    );

    // Create a PDO instance as db connection to a MySQL db.
    $db = new PDO(
            'mysql:host=localhost;port=3306;dbname=yourDB'
            , 'yourUser'
            , 'yourPass'
    );

    // Assign the driver options to the db connection.
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
    $db->setAttribute(PDO::ATTR_PERSISTENT, TRUE);

    // Iterate through tops and fetch the top areas.
    foreach ($tops as $top => $results) {
        // The sql statement - it will be prepared.
        $sql = 'SELECT 
                    cda.*,
                    (
                        SELECT (COUNT(DISTINCT value) + 1)
                        FROM country_development_areas
                        WHERE 
                            name = cda.name
                            AND value > cda.value
                    ) AS rankPositionInTheWorld,
                    (
                        SELECT (COUNT(DISTINCT value) + 1)
                        FROM country_development_areas
                        WHERE 
                            name = cda.name 
                            AND value > cda.value 
                            AND value >= :topDownLimit1 * (
                                SELECT SUM(IFNULL(value, 0)) 
                                FROM country_development_areas 
                                WHERE name = cda.name
                            )
                    ) AS rankPositionInTop 
                FROM country_development_areas AS cda
                WHERE
                    cda.country = :country AND
                    cda.value >= :topDownLimit2 * (
                        SELECT SUM(IFNULL(value, 0)) 
                        FROM country_development_areas 
                        WHERE name = cda.name
                    )';

        // The input parameters list for the prepared sql statement.
        $bindings = array(
            ':country' => $country,
            ':topDownLimit1' => 1 - $top / 100,
            ':topDownLimit2' => 1 - $top / 100,
        );

        // Prepare and validate the sql statement.
        $stmt = $db->prepare($sql);

        if (!$stmt) {
            throw new UnexpectedValueException('The sql statement could not be prepared!');
        }

        // Bind the input parameters to the prepared statement.
        foreach ($bindings as $key => $value) {
            // Get the name of the input parameter by its key in the bindings array.
            $inputParameterName = is_int($key) ? ($key + 1) : (':' . ltrim($key, ':'));

            // Get the PDO::PARAM_* constant, e.g the data type of the input parameter, by its value.
            if (is_int($value)) {
                $inputParameterDataType = PDO::PARAM_INT;
            } elseif (is_bool($value)) {
                $inputParameterDataType = PDO::PARAM_BOOL;
            } else {
                $inputParameterDataType = PDO::PARAM_STR;
            }

            // Bind and validate the binding of the input parameter.
            $bound = $stmt->bindValue($inputParameterName, $value, $inputParameterDataType);

            if (!$bound) {
                throw new UnexpectedValueException('An input parameter could not be bound!');
            }
        }

        // Execute the prepared statement.
        $executed = $stmt->execute();

        if (!$executed) {
            throw new UnexpectedValueException('The prepared statement could not be executed!');
        }

        /// Fetch and validate the areas list.
        $topAreas = $stmt->fetchAll(PDO::FETCH_ASSOC);

        if ($topAreas === FALSE) {
            throw new UnexpectedValueException('Fetching data failed!');
        }

        $tops[$top] = $topAreas;
    }

    // Close connecion.
    $connection = NULL;
} catch (PDOException $e) {
    $error[] = $e->getMessage();

    // My recommendation:
    // echo $e->getMessage();
    // $logger->log($e);
    // exit();
} catch (Exception $e) {
    $error[] = $e->getMessage();

    // My recommendation:
    // echo $e->getMessage();
    // $logger->log($e);
    // exit();
}
?>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Trophies test</title>

        <!-- ======================================= -->
        <!-- CSS resources -->
        <!-- ======================================= -->

        <!-- Font-Awesome -->
        <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" type="text/css" rel="stylesheet" />

        <!-- Bootstrap -->
        <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" type="text/css" rel="stylesheet" />

        <!-- ======================================= -->
        <!-- JS resources -->
        <!-- ======================================= -->

        <!-- jQuery -->
        <script src="https://code.jquery.com/jquery-3.2.1.min.js" type="text/javascript" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>

        <!-- Bootstrap -->
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" type="text/javascript"></script>

        <style type="text/css">
            body {
                padding: 30px 15px;
            }

            .legend {
                margin-bottom: 30px;
                max-width: 30%;
            }

            .legend-title {
                background-color: #eee;
            }

            .trophy-cabinet-title {
                margin-bottom: 10px;
            }

            .trophy-cabinet {
                margin-bottom: 20px;
            }

            .top-area {
                padding: 10px;
                border: 1px solid #ccc;
                border-radius: 4px;
                display: inline-block;
            }
        </style>
    </head>
    <body>

        <div class="list-group legend">
            <div class="list-group-item legend-title">
                Legend
            </div>
            <div class="list-group-item">
                WP: Rank position in the world
            </div>
            <div class="list-group-item">
                TP: Rank position in the top
            </div>
        </div>

        <?php
        // Just for testing, to see the areas list of all tops on screen.
        // echo '<pre>' . print_r($tops, TRUE) . '</pre>';
        ?>

        <?php
        foreach ($tops as $top => $areas) {
            /*
             * If the list of areas for the current top 
             * is not empty, then display the areas.
             */
            if ($areas) {
                ?>
                <div class="trophy-cabinet-title">
                    Trophy cabinet for top <?php echo $top; ?>%.
                </div>
                <div id="trophyCabinet<?php echo $top; ?>Percent" class="trophy-cabinet">
                    <?php
                    foreach ($areas as $area) {
                        $areaId = $area['id'];
                        $areaIcon = $area['icon'];
                        $areaTitle = $area['title'];
                        $areaRankPositionInTheWorld = $area['rankPositionInTheWorld'];
                        $areaRankPositionInTop = $area['rankPositionInTop'];
                        ?>
                        <a class="top-area top<?php echo $top; ?>percent" href="/nation=united_states_of_america/detail=trend?censusid=<?php echo $areaId; ?>" title="<?php echo $areaTitle; ?>: <?php echo $areaRankPositionInTheWorld; ?>">
                            <div class="trophy">
                                <i class="fa fa-<?php echo $areaIcon; ?>"></i> WP <?php echo $areaRankPositionInTheWorld; ?> &bullet; TP <?php echo $areaRankPositionInTop; ?>
                            </div>
                        </a>
                        <?php
                    }
                    ?>
                </div>
                <?php
            }
        }
        ?>

    </body>
</html>

已用数据:

我使用了以下数据:

========================================
Create table syntax
========================================

DROP TABLE IF EXISTS `country_development_areas`;

CREATE TABLE `country_development_areas` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `country` int(11) DEFAULT NULL,
  `name` varchar(100) DEFAULT NULL,
  `value` int(11) DEFAULT NULL,
  `icon` varchar(100) DEFAULT NULL,
  `title` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

========================================
Insert values syntax
========================================

INSERT INTO `country_development_areas` (`id`, `country`, `name`, `value`, `icon`, `title`)
VALUES
    (0,1,'Civil Rights',2,'hand-peace-o','Most Free People'),
    (1,1,'Economy',10,'area-chart','Most Efficient Economies'),
    (2,1,'Political Freedom',8,'handshake-o','Most Political Freedom'),
    (3,1,'Population',1,'users','Largest Population'),
    (4,2,'Civil Rights',100,'hand-peace-o','Most Free People'),
    (5,2,'Political Freedom',2,'handshake-o','Most Political Freedom');