Skip to content
Advertisement

Alphabetic ordering for names

I have been struggling with this for almost 2 days now and i just can not get it to work myself. Basically my goal is to make a list from A to Z, with values from a database. Example:

A
Adam
Antony

B
Betty
Britney

C
D
E
F
G
etc... (names come from the database, letters are generated by php) 

Now my php code looks like this:

$character = generatenames();

foreach($character as $card) {
  $card = array($card);
}

var_dump($card);
$array = array();

foreach($card as $value) {
  if (empty($array[$value[0]])){
    $array[$value[0]][] = $value[0];
  }
  $array[$value[0]][] = $value;
}

foreach (range('A', 'Z') as $alph) {
  if (empty($array[$alph])) {
    echo $alph . "<br>";
  } else {
    echo (implode("n", $array[$alph])) . "<br>";
  }
}

Now, it does work when i put strings inside the array and remove the foreach loop on top: $card = array("Betty", "Britney", "Adam", "Antony");

And my function (basically a query exector), looks like this:

function generatenames() {
  
  $statement = $pdo->prepare('SELECT name FROM `character` ORDER BY name');
  $statement -> execute();

  $result = $statement->fetchAll(PDO::FETCH_ASSOC);
  return $result;
}

I dont think there is anything wrong with the function itself but with the php code, i hope someone has the answer i have been looking for.

Advertisement

Answer

One solution could be to use PDO::FETCH_GROUP together with LEFT() to select the first letter in MySQL as first column of the result and group by this first column:

<?php
$host = '127.0.0.1';
$db   = 'test';
$user = 'test';
$pass = 'test';
$charset = 'utf8mb4';

$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false,
];
try {
    $pdo = new PDO($dsn, $user, $pass, $options);
} catch (PDOException $e) {
    throw new PDOException($e->getMessage(), (int)$e->getCode());
}

function escape_for_html_output($var) {
    return htmlspecialchars($var, ENT_QUOTES, 'UTF-8');
}

// See also https://phpdelusions.net/pdo#group
$array = $pdo->query('SELECT UPPER(LEFT(`name` , 1)), `name` FROM `character`')->fetchAll(PDO::FETCH_GROUP);
print_r($array);

foreach (range('A', 'Z') as $alph) {
    echo $alph . '<br>' . PHP_EOL;
    if (isset($array[$alph]) && is_array($array[$alph])) {
        foreach ($array[$alph] as $row) {
            echo escape_for_html_output($row['name']) . '<br>' . PHP_EOL;
        }
        echo '<br>' . PHP_EOL;
    }
}

Outputs:

Array
(
    [A] => Array
        (
            [0] => Array
                (
                    [name] => Adam
                )

            [1] => Array
                (
                    [name] => Antony
                )

        )

    [B] => Array
        (
            [0] => Array
                (
                    [name] => Betty
                )

            [1] => Array
                (
                    [name] => Britney
                )

        )

)
A<br>
Adam<br>
Antony<br>
<br>
B<br>
Betty<br>
Britney<br>
<br>
C<br>
D<br>
E<br>
F<br>
G<br>
H<br>
I<br>
J<br>
K<br>
L<br>
M<br>
N<br>
O<br>
P<br>
Q<br>
R<br>
S<br>
T<br>
U<br>
V<br>
W<br>
X<br>
Y<br>
Z<br>

Or just group it yourself in PHP:

<?php

function generatenames() {
    $host = '127.0.0.1';
    $db   = 'test';
    $user = 'test';
    $pass = 'test';
    $charset = 'utf8mb4';

    $dsn = "mysql:host=$host;dbname=$db;charset=$charset";
    $options = [
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_EMULATE_PREPARES   => false,
    ];
    try {
        $pdo = new PDO($dsn, $user, $pass, $options);
    } catch (PDOException $e) {
        throw new PDOException($e->getMessage(), (int)$e->getCode());
    }

    $statement = $pdo->prepare('SELECT `name` FROM `character` ORDER BY `name`');
    $statement -> execute();

    $result = $statement->fetchAll(PDO::FETCH_ASSOC);
    return $result;
}

function escape_for_html_output($var) {
    return htmlspecialchars($var, ENT_QUOTES, 'UTF-8');
}

$characters = generatenames();
$array = [];
foreach($characters as $row) {
    if (isset($row['name'])) {
        $letter = mb_strtoupper(mb_substr($row['name'], 0, 1));
        if (empty($array[$letter])){
            $array[$letter] = [];
        }
        $array[$letter][] = $row['name'];
    }
}
foreach (range('A', 'Z') as $alph) {
    echo $alph . '<br>' . PHP_EOL;
    if (isset($array[$alph]) && is_array($array[$alph])) {
        foreach ($array[$alph] as $name) {
            echo escape_for_html_output($name) . '<br>' . PHP_EOL;
        }
        echo '<br>' . PHP_EOL;
    }
}

Output should be exactly the same as above (just without the print_r() part).

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement