You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CodeIgniter集成GeoIp2报错:Class 'GeoIp2\Database\Reader'未找到

CodeIgniter 集成 GeoIP2 类找不到问题的解决

问题背景

按指南通过Composer安装GeoIP2-php库后,生成了public_html/vendor/maxmind、maxmind-db、geoip2目录。手动将public_html/vendor/geoip2/geoip2/src/下的文件复制到application/third_party/GeoIp2/vendor/GeoIp2/,并在application/libraries下创建了CI_GeoIp2.php。

最初出现application/third_party/GeoIp2/vendor/autoload.php: failed to open stream错误,复制public_html/vendor/maxmind-db下的autoload.php到对应目录后,又出现新错误:Class 'GeoIp2\Database\Reader' not found。已确认Reader.php文件存在,且复制了maxmind-db的src内容到对应目录,但问题仍未解决。

当前目录结构(修正排版后):

/application
├── third_party
│   ├── GeoIp2
│   │   ├── vendor
│   │   ├── composer.json
│   │   ├── GeoIp2/
│   │   │   ├── Database/
│   │   │   ├── Exception/
│   │   │   ├── Model/
│   │   │   ├── Record/
│   │   │   ├── WebService/
│   │   │   ├── ProviderInterface.php
│   │   │   └── Util.php
│   │   ├── MaxMind/DB/
│   │   │   └── Reader.php
│   │   └── autoload.php

附CI_GeoIp2.php代码:

<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');

/**
 * GeoIp2 Class
 *
 * @package       CodeIgniter
 * @subpackage  Libraries
 * @category      GeoIp2
 * @author        Timothy Marois <timothymarois@gmail.com>
 */
require_once( APPPATH . 'third_party/GeoIp2/vendor/autoload.php' );
use GeoIp2\Database\Reader;

class CI_GeoIp2 { 

    protected $record;
    protected $database_path = 'third_party/GeoIp2/GeoIP2-City.mmdb';

    public function __construct() {

        $ci =& get_instance();
        $reader = new Reader(APPPATH.$this->database_path);

        $ip = $ci->input->ip_address();
        if ($ci->input->valid_ip($ip)) {
            $this->record = $reader->city($ip);
        }

        log_message('debug', "CI_GeoIp2 Class Initialized");
    }


    /**
     * getState()
     * @return state
     */
    public function getState() {
        return $this->record->mostSpecificSubdivision->name;;
    }


    /**
     * getState()
     * @return country code "US/CA etc"
     */
    public function getCountryCode() {
        return $this->record->country->isoCode;
    }


    /**
     * getCity()
     * @return city name
     */
    public function getCity() {
        return $this->record->city->name;
    }


    /**
     * getZipCode()
     * @return Zip Code (#)
     */
    public function getZipCode() {
        return $this->record->postal->code;
    }


    /**
     * getRawRecord()
     * (if you want to manually extract objects)
     *
     * @return object of all items
     */
    public function getRawRecord() {
        return $this->record;
    }

}

核心原因

手动复制文件破坏了Composer的自动加载规则,自定义的autoload.php无法正确映射类的命名空间与文件路径,导致PHP找不到对应的类文件。

解决方案

方案1:直接使用项目根目录的Composer自动加载(推荐)

  1. 在CodeIgniter入口文件index.php中,添加根目录的Composer自动加载:
require_once FCPATH . 'vendor/autoload.php';
  1. 修改CI_GeoIp2.php,删除原有require_once行,保留use语句即可:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

use GeoIp2\Database\Reader;

class CI_GeoIp2 { 
    // 原有代码保持不变
}
  1. 确认GeoIP2-City.mmdb路径正确,建议放在application/third_party/GeoIp2/下,原有路径配置无需修改。

方案2:修复手动复制的自动加载问题

  1. 修正目录结构,确保application/third_party/GeoIp2/vendor/下的目录与Composer安装的结构完全一致:
/application/third_party/GeoIp2/
├── vendor/
│   ├── GeoIp2/
│   │   ├── Database/
│   │   │   └── Reader.php
│   │   ├── Exception/
│   │   ├── Model/
│   │   ├── Record/
│   │   ├── WebService/
│   │   ├── ProviderInterface.php
│   │   └── Util.php
│   ├── MaxMind/
│   │   └── DB/
│   │       └── Reader.php
│   └── autoload.php
├── composer.json
└── GeoIP2-City.mmdb
  1. 替换autoload.php内容,添加正确的PSR-4自动加载规则:
<?php

// 加载GeoIp2命名空间类
spl_autoload_register(function ($class) {
    $prefix = 'GeoIp2\\';
    $base_dir = __DIR__ . '/GeoIp2/';
    $len = strlen($prefix);
    if (strncmp($prefix, $class, $len) !== 0) return;
    $relative_class = substr($class, $len);
    $file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
    if (file_exists($file)) require $file;
});

// 加载MaxMind\DB命名空间类
spl_autoload_register(function ($class) {
    $prefix = 'MaxMind\\DB\\';
    $base_dir = __DIR__ . '/MaxMind/DB/';
    $len = strlen($prefix);
    if (strncmp($prefix, $class, $len) !== 0) return;
    $relative_class = substr($class, $len);
    $file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
    if (file_exists($file)) require $file;
});
  1. 确保CI_GeoIp2.php中的require_once路径正确,类实例化代码无误。

验证步骤

在Controller中加载并测试:

$this->load->library('CI_GeoIp2');
echo $this->ci_geoip2->getCountryCode();

访问页面,检查是否能正常获取IP对应的地理信息。

内容的提问来源于stack exchange,提问作者user20508390

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 10:05:35