여러 라이브러리를 사용하다 보면 네임스페이스 충돌, 버전 호환성 문제 등이 발생합니다. 이런 충돌을 해결하는 실용적인 방법들을 알아보겠습니다.
{
"require": {
"monolog/monolog": "^2.0",
"guzzlehttp/guzzle": "~7.0",
"symfony/console": "5.*"
},
"conflict": {
"old-package/conflicting": "*"
}
}
<?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();
}
}
<?php
if (class_exists('NewLibrary\Parser')) {
class MyParser extends NewLibrary\Parser {
// 새 버전 사용
}
} else {
class MyParser extends OldLibrary\Parser {
// 구 버전 호환
}
}
<?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);
}
}
<?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();
}
}
}
<?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);
<?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);
}
}
{
"scripts": {
"check-conflicts": [
"php -r \"if (class_exists('ConflictingClass')) { echo 'Conflict detected!'; exit(1); }\""
],
"post-install-cmd": [
"@check-conflicts"
]
}
}
<?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);
}
}
이러한 패턴들을 사용하면 라이브러리 충돌을 최소화하고 코드의 유연성을 높일 수 있습니다. 특히 의존성 주입과 어댑터 패턴은 장기적인 유지보수에 매우 유용합니다.