Разве мы не можем использовать метод извлечения, который мы установили по умолчанию в ATTR_DEFAULT_FETCH_MODE? - PullRequest
0 голосов
/ 02 ноября 2019

Я установил PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, по умолчанию в соединении, и теперь у меня проблема с fetchAll.

У меня проблема:

Notice: Undefined offset: 0 in C:\wamp\www\a\test.php on line 59

И строка 59:

if($sql->fetchAll()[0][0] !== '0' && $level !== 0){

Вот мой тип подключения:

$host = 'localhost';
$db   = 'demo';
$user = 'root';
$pass = '';
$charset = 'utf8mb4';

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

И вот запрос, который я пытаюсь: если я удаляю ATTR_DEFAULT_FETCH_MODE, он работает нормально, есть ли способ использовать оба?

function bootstrap_menu($pdo, $parent_id, $level = null) {
    $stmt = $pdo->prepare("SELECT * FROM categories WHERE parent_id =:parent_id");
    $stmt->bindParam(":parent_id", $parent_id, PDO::PARAM_INT);
    $stmt->execute();
    foreach ($stmt->fetchAll() as $row) {
        $sql = $pdo->prepare("SELECT count(*) FROM categories WHERE parent_id =:cat_id");
        $sql->bindParam(":cat_id", $row['cat_id'], PDO::PARAM_INT);
        $sql->execute();
        if($sql->fetchColumn()[0][0] !== '0' && $level !== 0){  
            echo "<li class=\"nav-item dropdown\">\n";
            echo "<a class=\"nav-link dropdown-toggle\" href=\"".htmlspecialchars($row['seo_url'])."\" id=\"navbarDropdown\" role=\"button\" data-toggle=\"dropdown\"
                    aria-haspopup=\"true\" aria-expanded=\"false\">\n";
            echo $row['cat_name'];
            echo "</a>\n";
            echo "<ul class=\"dropdown-menu\" aria-labelledby=\"navbarDropdown\">\n";
            bootstrap_menu($pdo, $row[0], $level - 1);
            echo "</ul>\n";
            echo "</li>\n";
        }elseif($level == 0){
            $my_class = htmlspecialchars($row['cat_name']);         
            if($my_class == 'Ana Sayfa'){
                echo "<li class=\"nav-item active\">\n";
                echo "<a href=\"".htmlspecialchars($row['seo_url'])."\" class=\"nav-link \">\n";
                echo htmlspecialchars($row['cat_name']);
                echo "</a>\n";
                echo "</li>\n";
            }else{
                echo "<li class=\"nav-item\">\n";
                echo "<a href=\"".htmlspecialchars($row['seo_url'])."\" class=\"nav-link\">\n";
                echo htmlspecialchars($row['cat_name']);
                echo "</a>\n";
                echo "</li>\n";
            }
        }
        else { 
            echo "<li class=\"dropdown-item\">";
            echo "<a href=\"".htmlspecialchars($row['seo_url'])."\" class=\"dropdown-item\">\n";
            echo htmlspecialchars($row['cat_name']);
            echo "</a>\n";
            echo "</li>\n";
        }
        unset($sql);
    }
    unset($stmt);
}

1 Ответ

1 голос
/ 02 ноября 2019

$sql->fetchAll()[0][0] означает просто первый столбец первого ряда. Уже есть метод для этого в PDO fetchColumn().

Вам просто нужно:

if($sql->fetchColumn() !== '0' && $level !== 0) 

или даже лучше

if($sql->fetchColumn() && $level !== 0)

Если по какой-либо причине вы все еще хотите использовать fetchAll(), вы можете передать стиль выборки в качестве аргумента. например $sql->fetchAll(\PDO::FETCH_BOTH)

Также во внешнем цикле foreach ($stmt->fetchAll() as $row) на самом деле не требуется. Просто foreach ($stmt as $row)

...