Почему не работает класс капчи?

Привет, всем! Я наткнулся на интересную <b><a href="https://phppot.com/php/contact-form-with-custom-image-captcha-validation-like-google-recaptcha/" rel="nofollow">капчу</a></b> и решил попробовать создать нечто подобное для своего сайта, используя классы (пожалуйста, пройдите со мной с пониманием, так как я новичок). <br/> Я разработал некоторый код, но столкнулся с трудностями: не знаю, как правильно передать данные из базы данных в класс. Кроме того, у меня возникают проблемы с генерацией капчи: сгенерированные числа не совпадают с ожидаемыми, иногда они вообще не появляются или повторяются, хотя это не должно происходить (прилагаю скриншот ниже). Буду признателен за любую помощь и советы! <br/> <pre><code class="php">class captcha
{

    private $pdo;

    function __construct($pdo)
    {
        $this-&gt;pdo = $pdo;
    }

    function getRecord()
    {
        $result = $this-&gt;pdo-&gt;query("SELECT `id` FROM tbl_term ORDER BY RAND() LIMIT 1");
        return $result-&gt;fetch(PDO::FETCH_COLUMN);
    }

    function getCaptchaIcons()
    {
        $captcha = $this-&gt;pdo-&gt;prepare("SELECT tbl_captcha_images.*, tbl_term.name FROM tbl_captcha_images 
        JOIN tbl_term ON tbl_captcha_images.term_id = tbl_term.id WHERE term_id != ? ORDER BY RAND() LIMIT 4");
		$captcha-&gt;execute([$this-&gt;getRecord()]);
		$captchaResult = $captcha-&gt;fetchAll();
        return $captchaResult;
    }

    function getRandomCaptchaId()
    {
		$captcha = $this-&gt;pdo-&gt;prepare("SELECT tbl_captcha_images.*, tbl_term.name FROM tbl_captcha_images 
        JOIN tbl_term ON tbl_captcha_images.term_id = tbl_term.id WHERE term_id = ? LIMIT 1");
		$captcha-&gt;execute([$this-&gt;getRecord()]);
		$captchaResult = $captcha-&gt;fetchAll();
        return $captchaResult;
    }
	
	function captchaF
  • 27 августа 2024 г. 15:24
Ответы на вопрос 1
Понять, что не работает в вашем классе капчи, можно, рассмотрев несколько возможных проблем и путей их решения. Давайте разберем ваш код и некоторые отдельные аспекты, которые могут быть источником ошибок.

### Возможные проблемы и их решения

1. **Неправильное получение данных**: 
   Вы передаете `term_id` в методе `getCaptchaIcons()` и `getRandomCaptchaId()` из метода `getRecord()`. Убедитесь, что в таблице `tbl_term` существуют записи и что они возвращают корректные данные.

   ```php
   function getRecord()
   {
       $result = $this->pdo->query("SELECT `id` FROM tbl_term ORDER BY RAND() LIMIT 1");
       return $result->fetch(PDO::FETCH_COLUMN);
   }
   ```

   Если в таблице `tbl_term` нет записей, то `getRecord()` вернет `null`, и это может приводить к ошибкам при выполнении запросов с `term_id`.

2. **Проверка на пустые результаты**: 
   Когда вы выполняете запросы, важно проверять, возвращаются ли данные и правильные ли они:

   ```php
   function getCaptchaIcons()
   {
       $term_id = $this->getRecord();
       if ($term_id === false) {
           // Обработка случая, когда не удалось получить ID
           return [];
       }

       $captcha = $this->pdo->prepare("SELECT tbl_captcha_images.*, tbl_term.name FROM tbl_captcha_images 
       JOIN tbl_term ON tbl_captcha_images.term_id = tbl_term.id WHERE term_id != ? ORDER BY RAND() LIMIT 4");
       $captcha->execute([$term_id]);
       return $captcha->fetchAll();
   }
   ```

3. **Повторы и отсутствие генерации капчи**: 
   Убедитесь, что метод `getRecord()` не возвращает один и тот же `term_id` для разных вызовов. Если ваше приложение использует кэширование или сессии, это может вызывать повторения.

   Чтобы избежать повторов, вы можете сохранить уже использованные `term_id` в массиве и исключить их из выборки.

4. **Проблема с HTML-выводом**: 
   В вашем примере отсутствует часть кода, которая отвечает за вывод капчи на экран. Поэтому убедитесь, что вы правильно формируете HTML на основе полученных данных.

5. **Убедитесь в правильности запроса к базе данных**: 
   Проверьте, что запросы к базе данных корректны, и возвращают ожидаемые результаты. Запросы можно протестировать непосредственно в вашей базе данных, чтобы удостовериться, что они работают.

### Улучшенный пример класса

Вот как может выглядеть улучшенный класс капчи с учетом указанных предложений:

```php
class Captcha
{
    private $pdo;

    function __construct($pdo)
    {
        $this->pdo = $pdo;
    }

    function getRecord()
    {
        $result = $this->pdo->query("SELECT `id` FROM tbl_term ORDER BY RAND() LIMIT 1");
        return $result->fetch(PDO::FETCH_COLUMN);
    }

    function getCaptchaIcons()
    {
        $term_id = $this->getRecord();
        if ($term_id === false) {
            return [];
        }

        $captcha = $this->pdo->prepare("SELECT tbl_captcha_images.*, tbl_term.name FROM tbl_captcha_images 
        JOIN tbl_term ON tbl_captcha_images.term_id = tbl_term.id WHERE term_id != ? ORDER BY RAND() LIMIT 4");
        $captcha->execute([$term_id]);
        return $captcha->fetchAll();
    }

    function getRandomCaptchaId()
    {
        $term_id = $this->getRecord();
        if ($term_id === false) {
            return [];
        }

        $captcha = $this->pdo->prepare("SELECT tbl_captcha_images.*, tbl_term.name FROM tbl_captcha_images 
        JOIN tbl_term ON tbl_captcha_images.term_id = tbl_term.id WHERE term_id = ? LIMIT 1");
        $captcha->execute([$term_id]);
        return $captcha->fetch();
    }

    // Добавьте другие методы по мере необходимости
}
```

### Резюме
Ваш класс капчи может быть улучшен за счет надежной обработки ошибок, правильного получения данных и проверки на пустые результаты. Также важно удостовериться, что HTML вывод правильный и соответствует полученным данным.
Похожие вопросы