Community연구 & 데이터 분석github.com

레거시 PHP → PHP 8.3/8.4 현대화 도구

PHP 5.x/7.x 기반의 레거시 코드베이스(커스텀 CMS, TemplatePower, mysql_*, ereg, short tags, PHP4 생성자)를 PHP 8.3/8.4에서 실행 가능하도록 인플레이스 업그레이드하고, .env 설정과 FTP/rsync deploy.sh를 통해 Docker 없이 배포합니다. 레거시 PHP CMS/사이트 및 유사 프로젝트 현대화, 또는 공유 호스팅(cPanel/Plesk)으로 FTP 이전 시 사용하세요.

8.4 현대화 도구란 무엇인가요?

이 스킬은 PHP 5.x/7.x에 갇힌 레거시 PHP 프로젝트를 PHP 8.3/8.4로 현대화하기 위한 포괄적인 툴킷입니다. mysql_, ereg, short tags, PHP4 스타일 생성자, bareword 배열 키 등 PHP 8에서 제거되거나 호환되지 않는 기능들을 자동으로 감지하고 수정하는 스크립트 모음을 제공합니다. 주요 기능으로는 1) mysql_*→mysqli 변환, ereg→preg 변환, 에러 처리기 등이 포함된 호환성 shim, 2) bareword 키와 가변 변수 구문을 자동 수정하는 파서, 3) 메서드 시그니처 호환성 검사기, 4) 커스텀 CMS, TemplatePower 기반 사이트, 다양한 레거시 프레임워크에 적용 가능한 공통 아키텍처 접근법이 있습니다. 또한 Docker 없이 FTP/rsync를 통한 공유 호스팅 배포를 지원하며, .env 기반 설정, Apache/PHP-FPM용 .htaccess, 안전한 TimThumb 대체, 자동화된 FTP 배포 스크립트 등을 제공합니다. Git 베이스라인, 단계별 수정, 지속적인 php -l 검증, HTTP 스모크 테스트를 통한 안전한 현대화 워크플로우를 따릅니다.

지원 대상~Claude Code~Codex CLI~Cursor✓OpenCode
npx skills add https://github.com/dbravoan/opencode-skills/tree/HEAD/skills/legacy-php8-modernizer

Installed? Explore more 연구 & 데이터 분석 skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

8.4 현대화 도구은(는) 무엇을 하나요?

언제 사용하나요

이 스킬은 레거시 PHP 프로젝트(보통 PHP 5.x용으로 작성된 커스텀 CMS)가 다음과 같은 경우에 유용합니다:

  • 전체 재작성 없이 PHP 8.3 / 8.4에서 실행되어야 할 때, 및/또는
  • Docker 없이 공유 호스팅(cPanel/Plesk)으로 FTP를 통해 배포되어야 할 때

일반적인 증상: mysql_*, ereg/eregi, <? short 태그, PHP4 스타일 생성자, bareword 배열 키($row[Id]), $$var['key'], sizeof(null), MyISAM 덤프, TemplatePower 템플릿, config/defines*.php에 평문 자격 증명.

이 스킬이 제공하는 것

자산목적
scripts/compat.phpShim: mysql_*→mysqli, ereg*/split→preg, userErrorHandler
scripts/fix_barewords.phpTokenizer 기반 bareword 배열 키 인용 처리
scripts/fix_variable_variables.phpPHP 8 $$var['key'] 균일 변수 구문 호환성 문제 수정
scripts/check_signatures.php정적 LSP 메서드 시그니처 검사기
scripts/lint-all.shphp -l 스윕
scripts/smoke-test.shURL 목록 HTTP 스모크 테스트
templates/defines.php.env 로더 + DB 상수 (Docker 유무와 관계없이 작동)
templates/env.example.env 템플릿 (DB_* + FTP_*)
templates/htaccess최신 Apache/PHP-FPM .htaccess
templates/user.ini공유 호스팅용 PHP-FPM 오버라이드
templates/timthumb.php안전한 GD 썸네일 생성기 (취약한 TimThumb 대체)
deploy/deploy.shFTP 또는 rsync 배포; 개발 파일 제외; 원격 .env 작성

황금 규칙

  1. 안전 우선: 건드리기 전에 git init + 베이스라인 커밋. DB를 백업하세요.
  2. 리팩터 전에 차단 해제: shim으로 전체 코드베이스를 즉시 실행 가능하게 만듭니다.
  3. 중앙 집중식 DB 레이어: dbClass를 먼저 교체/제한하고; shim은 raw mysql_* 호출을 처리합니다.
  4. 보안은 조기에: 사이트가 렌더링되는 즉시 위험한 도구와 TimThumb을 제거하세요.
  5. 지속적으로 검증: 모든 배치 후 php -l을 실행하고, 모든 URL을 스모크 테스트하세요.

절차

0. 베이스라인

git init -q && git add -A && git commit -qm "baseline: legacy PHP"
find . -name '*.php' -not -path './node_modules/*' | wc -l

scripts/smoke-test.sh를 위해 실제 공개 URL 목록(DB/사이트맵에서)을 저장하세요.

1. 호환성 shim 설치

  • scripts/compat.php를 includes/compat.php 등으로 복사하세요.
  • 부트스트랩의 가장 위쪽에서 레거시 코드보다 먼저 로드하세요:
    include_once(__DIR__.'/../includes/compat.php');
    
  • 이 shim은 mysql_*, ereg/eregi/ereg_replace/eregi_replace/split, mysqli_report(MYSQLI_REPORT_OFF) (SQL 오류는 예외 대신 false 반환), 그리고 userErrorHandler() (PHP 5의 오래된 E_NOTICE "undefined index/variable"를 억제)를 제공합니다.
  • 핸들러를 한 번 등록하세요:
    if (function_exists('userErrorHandler')) set_error_handler('userErrorHandler');
    

2. 기계적 수정 (스크립트)

php scripts/fix_barewords.php            # 드라이 런
php scripts/fix_barewords.php --apply
php scripts/fix_variable_variables.php   # 드라이 런
php scripts/fix_variable_variables.php --apply
scripts/lint-all.sh

그런 다음 린트가 여전히 보고하는 문제를 수정하세요:

  • Short 태그: <? → <?php (grep <\?(?!php|=|xml)).
  • PHP4 생성자: function ClassName() → function __construct().
  • 중괄호 문자열 오프셋: $s{0} → $s[0].
  • 루프/스위치 외부의 break (PHP 8에서 치명적 오류).
  • ${...} 내의 가변 변수: bareword 인용 / ${$var['k']} 사용.

3. 시그니처, 정적 & null 안전

php scripts/check_signatures.php

각 MISMATCH에 대해 자식 메서드에 기본 파라미터를 추가하세요 (예: $tabla = null). 그런 다음 런타임에 나타나는 치명적 오류를 수정하세요:

오류수정
ArgumentCountError: too few arguments후행 파라미터에 기본값 추가
정적 메서드에서 $thisself::/static:: 사용 또는 앱 컨텍스트 전달
method_exists(null, ...)is_object($x) && method_exists($x, ...)
Cannot access offset of type string on string$x['k'] 전에 is_array($x) 재정렬
Undefined constant "X"bareword 키/상수 인용
sizeof/count/array_keys(null)is_array($x) ? ... : ..., (array)$x
foreach(null)foreach ((array)$x as ...)
Accessing static property X as non static$this->prop → self::$prop

4. 실제 DB로 실행 및 반복

설정을 DB에 연결하고 모든 URL을 요청하세요. scripts/smoke-test.sh가 0 실패를 보고하고 로그에 경고가 없을 때까지 테스트당 하나의 치명적 오류를 수정하세요.

5. 보안 (조기에 수행)

  • TimThumb을 templates/timthumb.php로 교체하세요.
  • scanner.php, chmod777.php, info.php, 방치된 디버그 스크립트를 삭제하세요.
  • .htaccess가 .env, .git, config/defines.php, dotfiles를 거부하도록 만드세요.
  • 커밋된 DB 비밀번호를 교체하고; 비밀을 .env로 옮기세요.
  • CSRF 토큰, CSP/HSTS, 속도 제한, 준비된 문(Prepared Statements)을 권장합니다.

6. 설정 + 배포

  • templates/defines.php (.env 로더)와 templates/env.example를 사용하세요.
  • templates/htaccess와 templates/user.ini를 사용하세요.
  • deploy/deploy.sh로 배포하세요.

.env 시스템

config/defines.php는 프로젝트 루트에서 .env를 로드하며, getenv()로 대체하고 최종적으로 안전한 기본값으로 폴백합니다. 이는 동일한 DB_* 키를 사용하여 Docker가 계속 작동하도록 유지하면서, FTP 배포를 단일 파일 편집으로 만듭니다.

.env (커밋 금지):

DB_HOST=localhost
DB_NAME=cpaneluser_termospa
DB_USER=cpaneluser_termospa
DB_PASS=super-secret
DB_SUBDIRECTORIO=

배포 (Docker 없음)

공유 호스팅 (cPanel/Plesk) 체크리스트

  1. PHP: 8.3 (또는 8.1+) 선택; mysqli, gd, mbstring, pdo_mysql 활성화.
  2. DB: DB + 사용자 생성, 덤프 가져오기. MySQL 8의 경우:
    SET SESSION sql_mode='NO_ENGINE_SUBSTITUTION';
    
    utf8_spanish_ci → utf8mb3_spanish_ci 경고 예상 (또는 utf8mb4 마이그레이션 실행).
  3. 파일: public_html/에 업로드 (docker/, tools/, router.php, _DOCS/, .git/ 제외).
  4. 권한: 디렉토리 755, 파일 644; recursos/cache/, .cache/, upload/ 쓰기 가능 (775/777).
  5. 설정: 원격 .env 생성 (deploy.sh가 수행) 및 DB_* 확인.
  6. .htaccess에서 .env 액세스 차단.

deploy.sh

./deploy.sh ftp          # lftp 역방향 미러
./deploy.sh ftp --dry-run
./deploy.sh rsync        # SSH를 통한 rsync

이 스크립트는 .env (FTP_HOST/USER/PASS/PATH/TLS 또는 SSH_*)를 읽고, 런타임 파일만 스테이징하며, 서버에 FTP 자격 증명이 저장되지 않도록 DB_*만 포함하는 원격 전용 .env를 작성하고, 업로드한 후 권한/DB 단계를 출력합니다.


검증 체크리스트

  • scripts/lint-all.sh → 모두 깨끗
  • scripts/smoke-test.sh urls.txt → 0 실패
  • 홈 / 제품 / 프로젝트 / 뉴스 / 연락처 페이지 렌더링
  • /sitemap.xml 및 /rss가 유효한 XML 반환
  • /imagenes/thumbnail/...가 이미지 반환 (GD + 재작성)
  • /administracion/login/ 로드; 로그인 및 콘텐츠 관리자 작동
  • 연락처 양식 제출
  • 관리자 이미지 업로드가 upload/에 쓰기
  • 오류 로그에 PHP Warning/Fatal 없음

항상 문제를 일으키는 함정

  • mysqli_query는 PHP 8.1+에서 기본적으로 예외를 던짐; mysqli_report(MYSQLI_REPORT_OFF)를 호출하여 레거시 or die() / if($q=...)가 계속 작동하도록 하세요.
  • .htaccess의 php_flag / php_value는 PHP-FPM에서 HTTP 500을 유발 — .user.ini를 사용하세요.
  • PHP 8의 균일 변수 구문은 $$var['key']를 조용히 깨뜨림 (잘못된 변수에 씀) — fix_variable_variables.php를 실행하세요.
  • include()의 상대 경로는 스크립트 디렉토리/CWD를 기준으로 해석됨; __DIR__을 선호하세요.
  • PHP 8에서 사라짐: mysql_*, ereg*, split, create_function, each, magic quotes.
  • OPcache는 오래된 파일을 캐시함: 편집 후 FPM/Apache를 다시 시작하세요.
  • UTF-8: SET NAMES utf8mb4; 새 작업에서는 InnoDB + utf8mb4_unicode_ci를 선호하세요.

유사 프로젝트

이러한 CMS 프로젝트는 동일한 아키텍처를 공유합니다. 부트스트랩 경로와 썸네일 재작성 대상을 조정하여 동일한 절차를 따르세요. scripts/를 대상의 tools/에 복사하고, 프로젝트 루트에서 실행하세요.

관련 스킬