PHP에서 외부 라이브러리 충돌 문제 해결하기

프리터코더·2025년 6월 7일
0

php 문제 해결

목록 보기
66/79

여러 라이브러리를 사용하다 보면 네임스페이스 충돌, 버전 호환성 문제 등이 발생합니다. 이런 충돌을 해결하는 실용적인 방법들을 알아보겠습니다.

1. Composer 버전 제약 조건 설정

{
    "require": {
        "monolog/monolog": "^2.0",
        "guzzlehttp/guzzle": "~7.0",
        "symfony/console": "5.*"
    },
    "conflict": {
        "old-package/conflicting": "*"
    }
}

2. 네임스페이스 별칭 사용

<?php
// 같은 클래스명 충돌 해결
use Vendor1\Logger as Logger1;
use Vendor2\Logger as Logger2;

class MyService {
    private $primaryLogger;
    private $backupLogger;
    
    public function __construct() {
        $this->primaryLogger = new Logger1();
        $this->backupLogger = new Logger2();
    }
}

3. 조건부 클래스 로딩

<?php
if (class_exists('NewLibrary\Parser')) {
    class MyParser extends NewLibrary\Parser {
        // 새 버전 사용
    }
} else {
    class MyParser extends OldLibrary\Parser {
        // 구 버전 호환
    }
}

4. 어댑터 패턴으로 인터페이스 통일

<?php
interface LoggerInterface {
    public function log($message);
}

class MonologAdapter implements LoggerInterface {
    private $logger;
    
    public function __construct($monolog) {
        $this->logger = $monolog;
    }
    
    public function log($message) {
        $this->logger->info($message);
    }
}

class CustomLoggerAdapter implements LoggerInterface {
    public function log($message) {
        error_log($message);
    }
}

5. 팩토리 패턴으로 라이브러리 선택

<?php
class HttpClientFactory {
    public static function create() {
        if (class_exists('GuzzleHttp\Client')) {
            return new GuzzleHttpAdapter();
        } elseif (function_exists('curl_init')) {
            return new CurlAdapter();
        } else {
            return new FileGetContentsAdapter();
        }
    }
}

6. 의존성 주입으로 결합도 낮추기

<?php
class EmailService {
    private $mailer;
    
    public function __construct($mailer) {
        $this->mailer = $mailer; // 구체적인 라이브러리에 의존하지 않음
    }
    
    public function send($to, $subject, $body) {
        return $this->mailer->send($to, $subject, $body);
    }
}

// 사용
$swiftMailer = new SwiftMailerAdapter();
$emailService = new EmailService($swiftMailer);

7. 버전 체크 및 호환성 레이어

<?php
class DatabaseHelper {
    private $connection;
    
    public function __construct() {
        if (class_exists('PDO')) {
            $this->connection = new PDOAdapter();
        } elseif (function_exists('mysqli_connect')) {
            $this->connection = new MySQLiAdapter();
        } else {
            throw new Exception('지원되는 데이터베이스 확장이 없습니다');
        }
    }
    
    public function query($sql) {
        return $this->connection->execute($sql);
    }
}

8. Composer 스크립트로 충돌 감지

{
    "scripts": {
        "check-conflicts": [
            "php -r \"if (class_exists('ConflictingClass')) { echo 'Conflict detected!'; exit(1); }\""
        ],
        "post-install-cmd": [
            "@check-conflicts"
        ]
    }
}

9. 래퍼 클래스로 API 통일

<?php
class CacheManager {
    private $cache;
    
    public function __construct() {
        if (class_exists('Redis')) {
            $this->cache = new RedisCache();
        } elseif (class_exists('Memcached')) {
            $this->cache = new MemcachedCache();
        } else {
            $this->cache = new FileCache();
        }
    }
    
    public function get($key) {
        return $this->cache->retrieve($key);
    }
    
    public function set($key, $value, $ttl = 3600) {
        return $this->cache->store($key, $value, $ttl);
    }
}

이러한 패턴들을 사용하면 라이브러리 충돌을 최소화하고 코드의 유연성을 높일 수 있습니다. 특히 의존성 주입과 어댑터 패턴은 장기적인 유지보수에 매우 유용합니다.

profile
일용직 개발자. freetercoder@gmail.com

0개의 댓글