потому что execute() возвращает не то что ты думаешь, а тыкву.
о чем тебе недвусмысленно текст ошибки и сообщает
"без prepare возвращает" потому что query() возвращает объект класса PDOStatement, в котором есть метод fetchAll.
а execute - это УЖЕ метод объекта $stmt класса PDOStatement, который возвращает БУЛЕВО значение
и fetchAll надо вызывать из того же объекта, то есть из $stmt, а не из результата execute
чтобы решить данную проблему и заодно избавиться от лишнего вызова execute() применим немого магии
class MyPDO extends PDO
{
public function preparedQuery($sql, $args = NULL)
{
if (!$args)
{
return $this->query($sql);
}
$stmt = $this->prepare($sql);
$stmt->execute($args);
return $stmt;
}
}
и дальше уже создав экземпляр этого класса обычным порядком,
$in_arr = ['meter', 'kilometer'];
$count_arr = count($in_arr);
$in_questions = str_repeat('?,', $count_arr - 1) . '?';
$sql = "SELECT * FROM `cpl_names` WHERE `type` = 'length' AND `id` IN ($in_questions)";
$result = $mypdo->preparedQuery($sql, $in_arr)->fetchAll();