├── .gitignore ├── Captcha.php ├── CaptchaInterface.php ├── LICENSE ├── README.md └── composer.json /.gitignore: -------------------------------------------------------------------------------- 1 | # phpstorm project files 2 | .idea 3 | 4 | # composer vendor dir 5 | /vendor 6 | 7 | # composer itself is not needed 8 | composer.phar 9 | composer.lock -------------------------------------------------------------------------------- /Captcha.php: -------------------------------------------------------------------------------- 1 | 'Нет свободных работников в данный момент, попробуйте позже либо повысьте свою максимальную ставку здесь', 93 | 'ERROR_ZERO_CAPTCHA_FILESIZE' => 'Размер капчи которую вы загружаете менее 100 байт', 94 | 'ERROR_TOO_BIG_CAPTCHA_FILESIZE' => 'Ваша капча имеет размер более 100 килобайт', 95 | 'ERROR_ZERO_BALANCE' => 'Нулевой либо отрицательный баланс', 96 | 'ERROR_IP_NOT_ALLOWED' => 'Запрос с этого IP адреса с текущим ключом отклонен. Пожалуйста смотрите раздел управления доступом по IP', 97 | 'ERROR_CAPTCHA_UNSOLVABLE' => 'Не смог разгадать капчу', 98 | 'ERROR_BAD_DUPLICATES' => 'Функция 100% распознавания не сработала и-за лимита попыток', 99 | 'ERROR_NO_SUCH_METHOD' => 'Вы должны слать параметр method в вашем запросе к API, изучите документацию', 100 | 'ERROR_IMAGE_TYPE_NOT_SUPPORTED' => 'Невозможно определить тип файла капчи, принимаются только форматы JPG, GIF, PNG', 101 | 'ERROR_KEY_DOES_NOT_EXIST' => 'Использован несуществующий key', 102 | 'ERROR_WRONG_USER_KEY' => 'Неверный формат параметра key, должно быть 32 символа', 103 | 'ERROR_WRONG_ID_FORMAT' => 'Неверный формат ID каптчи. ID должен содержать только цифры', 104 | 'ERROR_WRONG_FILE_EXTENSION' => 'Ваша каптча имеет неверное расширение, допустимые расширения jpg,jpeg,gif,png', 105 | ]; 106 | 107 | private $captcha_id; 108 | 109 | public function setApiKey($apiKey) 110 | { 111 | if (is_callable($apiKey)) { 112 | $this->apiKey = $apiKey(); 113 | } else { 114 | $this->apiKey = $apiKey; 115 | } 116 | } 117 | 118 | /** 119 | * Запуск распознавания капчи 120 | * @param string $filename Путь до файла или ссылка на него 121 | * @return bool 122 | */ 123 | public function run($filename) 124 | { 125 | $this->result = null; 126 | $this->error = null; 127 | try { 128 | if (strpos($filename, 'http://') !== false || strpos($filename, 'https://') !== false) { 129 | $current = file_get_contents($filename); 130 | if ($current) { 131 | $path = \Yii::getAlias($this->pathTmp) . '/' . \Yii::$app->security->generateRandomString(); 132 | if (file_put_contents($path, $current)) { 133 | $filename = $path; 134 | } else { 135 | throw new Exception("Нет доступа для записи файла"); 136 | } 137 | } else { 138 | throw new Exception("Файл {$filename} не загрузился"); 139 | } 140 | } elseif (!file_exists($filename)) { 141 | throw new Exception("Файл {$filename} не найден"); 142 | } 143 | $postData = [ 144 | 'method' => 'post', 145 | 'key' => $this->apiKey, 146 | 'file' => (version_compare(PHP_VERSION, '5.5.0') >= 0) ? new \CURLFile($filename) : '@' . $filename, 147 | 'phrase' => $this->isPhrase, 148 | 'regsense' => $this->isRegSense, 149 | 'numeric' => $this->isNumeric, 150 | 'min_len' => $this->minLen, 151 | 'max_len' => $this->maxLen, 152 | 'language' => $this->language, 153 | 'soft_id' => 882, 154 | ]; 155 | $ch = curl_init(); 156 | curl_setopt($ch, CURLOPT_URL, "http://{$this->domain}/in.php"); 157 | if (version_compare(PHP_VERSION, '5.5.0') >= 0 && version_compare(PHP_VERSION, '7.0') < 0) { 158 | curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false); 159 | } 160 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 161 | curl_setopt($ch, CURLOPT_TIMEOUT, 60); 162 | curl_setopt($ch, CURLOPT_POST, 1); 163 | curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); 164 | $result = curl_exec($ch); 165 | if (curl_errno($ch)) { 166 | throw new Exception("CURL вернул ошибку: " . curl_error($ch)); 167 | } 168 | curl_close($ch); 169 | $this->setError($result); 170 | list(, $this->captcha_id) = explode("|", $result); 171 | $waitTime = 0; 172 | sleep($this->requestTimeout); 173 | while (true) { 174 | $result = file_get_contents("http://{$this->domain}/res.php?key={$this->apiKey}&action=get&id={$this->captcha_id}"); 175 | $this->setError($result); 176 | if ($result == "CAPCHA_NOT_READY") { 177 | $waitTime += $this->requestTimeout; 178 | if ($waitTime > $this->maxTimeout) { 179 | break; 180 | } 181 | sleep($this->requestTimeout); 182 | } else { 183 | $ex = explode('|', $result); 184 | if (trim($ex[0]) == 'OK') { 185 | $this->result = trim($ex[1]); 186 | return true; 187 | } 188 | } 189 | } 190 | throw new Exception('Лимит времени превышен'); 191 | } catch (Exception $e) { 192 | $this->error = $e->getMessage(); 193 | return false; 194 | } 195 | } 196 | 197 | /** 198 | * Не верно распознана 199 | */ 200 | public function notTrue() 201 | { 202 | file_get_contents("http://{$this->domain}/res.php?key={$this->apiKey}&action=reportbad&id={$this->captcha_id}"); 203 | } 204 | 205 | /** 206 | * Результат 207 | * @return null|string 208 | */ 209 | public function result() 210 | { 211 | return $this->result; 212 | } 213 | 214 | /** 215 | * Ошибка 216 | * @return null|string 217 | */ 218 | public function error() 219 | { 220 | return $this->error; 221 | } 222 | 223 | /** 224 | * Проверка на то произошла ли ошибка 225 | * @param $error 226 | * @throws Exception 227 | */ 228 | private function setError($error) 229 | { 230 | if (strpos($error, 'ERROR') !== false) { 231 | if (array_key_exists($error, $this->errors)) { 232 | throw new Exception($this->errors[$error]); 233 | } else { 234 | throw new Exception($error); 235 | } 236 | } 237 | } 238 | } 239 | -------------------------------------------------------------------------------- /CaptchaInterface.php: -------------------------------------------------------------------------------- 1 | [ 42 | 'captcha' => [ 43 | 'class' => 'jumper423\Captcha', 44 | 'pathTmp' => '@app/captcha', 45 | 'apiKey' => '42eab4119020dbc729f657fef270r546', 46 | ], 47 | ], 48 | ``` 49 | 50 | Использование 51 | ------------ 52 | Простой пример использования: 53 | 54 | ```php 55 | $path = 'path/to/captcha.png'; 56 | if (\Yii::$app->captcha->run($path)) { 57 | $captcha = \Yii::$app->captcha->result(); 58 | } else { 59 | throw new Exception(\Yii::$app->captcha->error()); 60 | } 61 | ``` 62 | 63 | Так же можно применять если у Вас есть только ссылка на капчу, но для этого метода Вам следует прописать путь в конфигурации для сохранения капч (pathTmp): 64 | 65 | ```php 66 | $url = 'https://vk.com/captcha.php?sid=698254154192&s=1'; 67 | if (\Yii::$app->captcha->run($url)) { 68 | $captcha = \Yii::$app->captcha->result(); 69 | } else { 70 | throw new Exception(\Yii::$app->captcha->error()); 71 | } 72 | ``` 73 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jumper423/yii2-captcha", 3 | "description": "Распознавание капч для всех популярных сервисов rucaptcha.com, 2captcha.com, pixodrom.com, captcha24.com, socialink.ru, anti-captcha.com", 4 | "keywords": ["yii2", "captcha", "recognition", "rucaptcha.com", "2captcha.com", "pixodrom.com", "captcha24.com", "socialink.ru", "rucaptcha", "2captcha", "pixodrom", "captcha24", "socialink", "anti-captcha.com", "anti-captcha"], 5 | "homepage": "http://infoblog1.ru/learn/cms/yii/raspoznavanie-kapch-na-yii2", 6 | "type": "project", 7 | "license": "Apache License 2.0", 8 | "support": { 9 | "issues": "https://github.com/jumper423/yii2-captcha/issues?state=open", 10 | "source": "https://github.com/jumper423/yii2-captcha" 11 | }, 12 | "minimum-stability": "stable", 13 | "require": { 14 | "php": ">=5.4.0", 15 | "yiisoft/yii2": "*" 16 | }, 17 | "config": { 18 | "process-timeout": 1800 19 | }, 20 | "autoload": { 21 | "psr-4": {"jumper423\\": ""} 22 | } 23 | } 24 | --------------------------------------------------------------------------------