load(); \support\App::loadAllConfig(['route']); use app\miniapi\auth\SmsCode; use app\miniapi\model\MiniSmsCode; use app\miniapi\model\MiniUser; $endpoint = (string) config('mini_api.sms_endpoint', ''); $host = parse_url($endpoint, PHP_URL_HOST); $signature = trim((string) config('mini_api.sms_signature', '')); $checks = [ 'curl' => extension_loaded('curl'), 'mbstring' => extension_loaded('mbstring'), 'pdo_mysql' => extension_loaded('pdo_mysql'), 'sms_enabled_with_credentials' => SmsCode::enabled(), 'signature_configured' => $signature !== '', 'https_endpoint' => parse_url($endpoint, PHP_URL_SCHEME) === 'https' && in_array($host, ['api.smsbao.com', 'www.smsbao.com'], true) && parse_url($endpoint, PHP_URL_PATH) === '/sms' && parse_url($endpoint, PHP_URL_QUERY) === null, ]; $report = [ 'php_binary' => PHP_BINARY, 'php_ini' => php_ini_loaded_file(), 'additional_ini' => php_ini_scanned_files() ?: null, 'curl_cainfo' => ini_get('curl.cainfo') ?: null, 'openssl_cafile' => ini_get('openssl.cafile') ?: null, 'sms_host' => $host, 'signature' => $signature !== '' ? $signature : null, ]; foreach ([ 'mini_user_phone_schema' => [new MiniUser(), ['id', 'phone', 'status']], 'sms_code_schema' => [new MiniSmsCode(), ['id', 'phone', 'purpose', 'code_hash', 'attempts', 'expires_at', 'consumed_at', 'request_ip', 'created_at']], ] as $name => [$model, $columns]) { try { $model->newQuery()->select($columns)->limit(1)->get(); $checks[$name] = true; } catch (\Throwable $exception) { $checks[$name] = false; $report['database_errors'][$name] = [ 'type' => get_class($exception), 'code' => $exception->getCode(), ]; } } if (in_array('--gateway', $argv, true)) { if (!$checks['curl'] || !$checks['sms_enabled_with_credentials'] || !$checks['https_endpoint']) { $checks['gateway'] = false; $report['gateway'] = ['skipped' => 'Fix the extension, account or endpoint checks first.']; } else { $username = (string) config('mini_api.sms_user', ''); $credential = (string) config('mini_api.sms_password', ''); $url = 'https://' . $host . '/query?' . http_build_query(['u' => $username, 'p' => $credential]); $curl = curl_init($url); curl_setopt_array($curl, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 5, CURLOPT_TIMEOUT => 10, CURLOPT_SSL_VERIFYPEER => true, CURLOPT_SSL_VERIFYHOST => 2, CURLOPT_FOLLOWLOCATION => false, ]); $raw = curl_exec($curl); $httpStatus = curl_getinfo($curl, CURLINFO_HTTP_CODE); $errorNumber = curl_errno($curl); $error = curl_error($curl); curl_close($curl); $lines = $raw === false ? [] : preg_split('/\r?\n/', trim($raw)); $status = $lines[0] ?? ''; $checks['gateway'] = $httpStatus === 200 && $status === '0'; $report['gateway'] = [ 'http_status' => $httpStatus, 'curl_errno' => $errorNumber, 'provider_status' => preg_match('/^-?\d+$/D', $status) ? $status : null, ]; if ($error !== '') { $report['gateway']['transport_error'] = str_replace( [$url, rawurlencode($credential), $credential, $username], '[redacted]', $error ); } if ($checks['gateway'] && preg_match('/^\d+,\d+$/D', $lines[1] ?? '')) { [$sent, $remaining] = explode(',', $lines[1]); $report['gateway']['remaining_sms'] = (int) $remaining; } } } $report['checks'] = $checks; $report['ok'] = !in_array(false, $checks, true); echo json_encode($report, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . PHP_EOL; exit($report['ok'] ? 0 : 1);