Skip to content

About

PHP 8.x PDO/Native connector module for CUBRID, Refer @CUBRID/cubrid-pdo and @CUBRID/cubrid-php, @deokio/textcube-ng

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

License

This project is licensed under the PHP License v3.01 (inheriting the original license from CUBRID's native PHP extension).

  • Commercial Use: Allowed (Permissive License)
  • Source Code Closure: You are NOT required to open your application's source code when using or distributing this extension.
  • For more details, please refer to the LICENSE and NOTICE files.

CUBRID PHP 드라이버 테스트 환경 (네이티브 cubrid · PDO_CUBRID)

Textcube Cubrid 어댑터 점검용. 업스트림 드라이버는 PHP 7.x 까지만 빌드되므로 PHP 8 지원 패치를 직접 작성했다. 대상: PHP 7.4 / 8.2 / 8.4 / 8.5, CUBRID 11.4 서버.

구성

경로 내용
Containerfile localhost/php-db:<V> 위에 두 확장을 빌드한 이미지(localhost/php-cubrid:<V>)
build_ext.sh 컨테이너 안 빌드 스크립트(패치 적용 → phpize/configure/make → 활성화)
patches/ cubrid-php.patch, cubrid-pdo.patch (기준 커밋은 patches/README.txt)
src/ 업스트림 원본(CUBRID/cubrid-php, cubrid-pdo develop + cci-src 서브모듈). 수정하지 않음
work/ 패치 작업본(git 작업 트리) — 패치는 여기서 생성. 빌드·시험 로그 work/log/
server_setup.sh CUBRID 서버 컨테이너 tccub-db 기동 + SSL 브로커(33100) 추가
dev_compile.sh 작업본 반복 컴파일(-Wall) · 단일 확장 smoke
run_tests.sh 이미지별 시험 일괄 실행(native · smoke · persist · close · lob · reuse · adapter native/pdo)
tests/smoke.php 네이티브·PDO 기본 동작
tests/close.php 네이티브 cubrid_close_request 뒤 변수 해제(시스템 malloc USE_ZEND_ALLOC=0 으로 실행)
tests/lob.php 네이티브 LOB resource 닫기(cubrid_lob_get/cubrid_lob_close·cubrid_lob2_close·LOB 를 가진 요청·연결 닫기, USE_ZEND_ALLOC=0)
tests/reuse.php 네이티브 연결(영구 연결 포함)을 닫은 뒤의 요청·LOB·열 정보, prepared 재실행의 열별 상태(USE_ZEND_ALLOC=0)
tests/native.php 네이티브 cubrid_* 함수 전반(출력을 원본 7.4 확장과 diff 로 비교)
tests/persist.php PDO 영구 연결의 요청 간 재사용(php -S)
tests/adapter.php Textcube framework/data/Cubrid/Adapter.php 실서버 점검($database['driver'] native · pdo)

사용법 (호스트 Git Bash)

# 1) 서버 (네트워크 tcpgnet, DB tc / 계정 tc / 암호 tcpw, 브로커 33000 · SSL 33100)
sh cubrid_pdo/server_setup.sh

# 2) 이미지 (V = 7.4 | 8.2 | 8.4 | 8.5)
podman build --build-arg V=8.5 -t localhost/php-cubrid:8.5 -f cubrid_pdo/Containerfile cubrid_pdo
#    업스트림 그대로(비교 기준): --build-arg V=7.4 --build-arg PATCH=0 -t localhost/php-cubrid:7.4-orig (PHP 7.4 에서만 빌드됨)

# 3) 시험 (결과: cubrid_pdo/work/log/test-<태그>-<시험>.txt)
sh cubrid_pdo/run_tests.sh              # 7.4-orig 7.4 8.2 8.4 8.5 전부
sh cubrid_pdo/run_tests.sh 8.5          # 하나만

# 작업본 수정 후 빠른 컴파일·점검
sh cubrid_pdo/dev_compile.sh 8.5 cubrid-pdo test

tests/native.php 는 마지막에 의도적으로 Fatal(없는 클래스로 cubrid_fetch_object)을 내므로 종료코드 255 가 정상. 버전 간 비교는 LOB 파일 이름·CAS 정보를 지우고 diff: sed -e 's#file:ces_[0-9]*/tc\.tc_nt\.[0-9_]*#file:<lob>#' -e 's#\[CAS INFO-[^]]*\]#[CAS INFO]#g'

패치 내용 (요약)

공통: config.m4 가 PHP 7 이상에서 *7.c 소스를 쓰도록 변경, TSRMLS 등 PHP 8 에서 없어진 매크로 보완.

네이티브 (cubrid-php)

  • PHP 8 API: fci.named_params, zend_ce_exception, ZSTR_VAL(), 별칭 함수 arginfo 누락
  • cubrid_put 숫자 값 변환이 포인터 주소를 변환하던 문제
  • cubrid_put($c, $oid, array): 빈 배열·정수 키에서 초기화 안 된 메모리 해제·NULL 역참조로 프로세스 종료, 빈 배열 SET 값이 앞 속성의 SET 을 재사용해 이중 해제 → 각각 오류 반환 / NULL 저장
  • true/false 값이 NULL 로 저장(PHP 7 에는 단일 bool 형식이 없어 _IS_BOOL 비교가 항상 거짓) → PHP 5 원본처럼 "Invalid type" 오류
  • 배열의 참조 원소(&$x)가 NULL 로 저장(SET 은 "Invalid type") → 참조를 풀어 값 사용
  • cubrid_put·SET 값·cubrid_get 속성 이름 배열·cubrid_db_name 이 호출자 배열을 제자리 변환 (스크립트의 리터럴 배열, opcache 공유 메모리의 배열 포함) → 복사본을 변환, 배열 내부 포인터도 건드리지 않음
  • close_cubrid_connect 초기화 안 된 포인터 사용
  • 연결 URL 버퍼 NUL 종료 누락(strncpy)
  • cubrid_fetch_object 클래스 이름 처리(문자열 아닌 값·경고 메시지), fci.object 형식 오류
  • cubrid_close_request: PHP 변수가 가진 resource 참조까지 놓아(zend_list_delete), 다른 질의를 실행한 뒤(기본 요청이 아닌 요청) 닫으면 변수가 해제된 메모리를 가리킴 → 기본 요청의 참조만 놓고 zend_list_close 로 닫음. 요청 resource 가 아니면(이미 닫힘·연결·resource 아님) false
  • LOB resource: cubrid_lob_get 이 반환 배열을, cubrid_lob_close 가 인자 배열을 resource 로 다룸(메모리 손상), cubrid_lob2_close 가 resource 를 지워 변수가 해제된 메모리를 가리킴, cubrid_lob_get LOB 해제 함수가 비어 있음(누수), 요청의 LOB 목록·연결을 닫은 뒤의 LOB 가 해제된 LOB·연결을 가리킴 → 각 LOB 를 zend_list_close 로 닫고(닫힌 resource 형식 'Unknown') 해제 함수에서 CCI LOB 해제, 요청 목록에서 뺌, 연결마다 LOB2 목록을 두고 연결을 닫을 때 떼어냄
  • 연결 닫기: close_cubrid_pconnect 가 남은 요청의 연결·핸들을 비우지 않아 cubrid_pconnect 연결을 닫은 뒤 요청·LOB 가 해제된 연결을 가리킴(목록 노드 누수), 요청의 열 정보가 연결을 끊을 때 CCI 가 해제한 메모리를 가리킴, 연결이 닫힌 요청의 cubrid_affected_rows·LOB 형식 cubrid_bind NULL 역참조 → 일반·영구 연결이 같은 정리(detach_cubrid_requests, 열 정보는 열 0개)를 거침, 닫힌 연결이면 'Invalid connection handle'(-20002) 오류와 -1 / false
  • prepared 재실행(cubrid_execute($req))이 열별 목록(lob2_list·field_lengths)을 이전 결과 크기로 둠(열 수가 늘면 범위 밖 쓰기), 이전 결과 마지막 행 LOB 가 계속 유효 → cubrid_next_result 처럼 정리(field_lengths 는 있던 경우에만 새 열 수로)

PDO (cubrid-pdo)

  • PHP 8.1+ PDO 드라이버/문장 API 대응(handler 시그니처, get_col 새 형식, PDO_PARAM_ZVAL·param_type 제거, 스트림 ssize_t)
  • 생성자 정수 키 옵션(ATTR_ERRMODE 등)이 거부되던 문제
  • 오류 코드 부호, NULL 오류 메시지, 초기화 안 된 오류 구조체, cci_get_db_version 반환값 미확인
  • 연결 URL: 사용자 없을 때 "(null)" 전송, 암호를 URL 에 넣어 : ? 가 든 암호가 다른 속성으로 해석되던 문제 → 암호·계정은 URL 밖 인자로
  • exec()·check_liveness 요청 핸들 누수, 문장 목록(stmt_list) 무한 증가, 변환 SQL 누수, 연결 실패 시 누수
  • 영구 연결: 요청 메모리의 stmt_list 를 다음 요청에서 사용 → 요청 종료 시 정리
  • AUTOCOMMIT 속성: bool 값을 정수로 읽음 / 정수가 아닌 값의 Z_LVAL_P
  • getColumnMeta: NULL 문자열 처리. PHP 8 코어가 빼버린 pdo_type·len 을 PHP 7 과 같은 규칙·키 순서로 채움
  • SET 바인딩: 호출자 배열을 변경, 집합 형식 미초기화, BIT 변환 버퍼 크기·해제 대상 오류, str2bit 누수
  • LOB 바인딩: 읽기 오류 시 무한 반복, 오류 시 사용자 스트림을 닫음, 실행 실패 시 LOB 누수, 한 문장의 LOB 파라미터가 여럿이면 마지막 것만 보관해 나머지 CCI LOB 핸들이 해제되지 않던 문제 → 목록으로 보관해 실행마다 모두 해제

사용 시 주의

  • PDO::quote() 는 escape 만 하고 따옴표를 붙이지 않는다(업스트림 규약). ' 로 직접 감쌀 것.
  • PARAM_LOB 에 문자열을 주면 그 문자열을 파일 경로로 열어 내용을 넣는다(업스트림 기능). 사용자 입력을 이렇게 바인딩하면 안 된다.
  • 네이티브 OID 함수(cubrid_put·cubrid_get 등)는 DONT_REUSE_OID 로 만든 테이블에서만 동작한다. CUBRID 10 이상의 기본 테이블(REUSE_OID)은 OID 가 @0|0|0 이라 쓸 수 없다.
  • OID 갱신은 자동 커밋되지 않는다. cubrid_commit() 을 하지 않으면 행 잠금이 남고, 연결을 끊을 때 롤백된다.
  • PHP 8.5 에서는 PDO::cubrid_schema() 를 호출할 때 E_DEPRECATED 경고가 난다(드라이버 전용 메서드 호출 방식 폐지 예고).
  • Textcube 어댑터를 $database['driver'] = 'pdo' 로 쓸 때: PDO SQL 파서가 :이름 을 자리표시자로 고쳐 쓸 문장(따옴표 해석이 서버와 다른 경우, 주로 PHP 8.4 미만)은 실행하지 않고 실패로 돌려준다. SSL 은 네이티브와 같이 암호화만(인증서 검증 없음, ssl_verify 를 켜면 연결하지 않음). server·database 에 DSN 구분자(; = 등)가 있으면 연결하지 않는다.
  • 업스트림 네이티브 확장(패치 없음)은 위 cubrid_close_request 결함이 그대로다. Textcube 네이티브 모드(free()·prepared close())가 이 함수를 쓰므로 패치한 확장이나 PDO 모드를 쓸 것. cubrid_lob_get·cubrid_lob_close·cubrid_lob2_close 와 LOB 를 가진 요청·연결 닫기도 해제된 메모리를 건드린다(Textcube 미사용, 패치 확장은 수정). 영구 연결을 닫은 뒤 남은 요청·연결이 닫힌 요청·열 수가 바뀌는 prepared 재실행도 같다(Textcube 어댑터는 cubrid_connect·같은 열 수의 LOB 없는 재실행만 써서 해당 없음, 패치 확장은 수정).
  • 패치 확장 LOB: cubrid_lob_close 는 LOB 가 아닌 원소에서 멈춘다(앞 원소는 닫힘, PHP 5 원본과 같음). 결과를 끝까지 읽은 뒤·cubrid_next_result·prepared 재실행(이전 결과 마지막 행)·연결을 닫은 뒤의 LOB 는 읽기·쓰기·cubrid_lob2_close 모두 'Invalid CUBRID-Lob2 resource' 경고와 false(업스트림 규칙, 변수를 놓을 때 해제). 요청만 닫으면 마지막 행 LOB 는 연결을 닫기 전까지 쓸 수 있다.
  • 패치 확장 연결 닫기: 닫은 연결(영구 포함)의 요청은 CCI 오류 경고와 false(cubrid_affected_rows 는 -1), 열 정보 함수는 열 0개로 답한다. cubrid_pconnect 연결도 요청 목록에 등록되어 요청이 끝나면 닫힌다(업스트림 동작). 확장의 php_cubrid_persistent_helper(영구 목록 정리)는 영구 목록에 등록된 연결이 없어 실행되지 않는 코드라 그대로 두었다.
  • PDO 는 BLOB·CLOB 열을 스트림으로 돌려준다(네이티브 cubrid_fetch 는 LOB 위치 문자열 file:…, CUBRID_LOB 를 주면 LOB resource). Textcube Cubrid 스키마에는 LOB 열이 없다.

그 밖의 동작 차이

  • PARAM_LOB 은 항상 BLOB. CLOB 은 PARAM_STR 문자열로 넣는다.
  • SET 열 바인딩은 PARAM_INT 등으로(PARAM_STR 배열은 PDO 코어가 "Array" 로 바꿈).
  • PHP 8.4+: PDO SQL 파서가 백슬래시 escape 를 인식하지 않음(CUBRID 기본 no_backslash_escapes=yes 와 일치).
  • CUBRID 11 getColumnMeta()['table'] 은 소유자 포함 이름(tc.smoke_p).
  • 네이티브 phpversion('cubrid') 는 빈 값(업스트림 모듈 버전 미설정).
  • 빌드 로그의 libtool *** Warning: Linking the shared library … against the static library 는 CCI 정적 라이브러리 링크 안내(컴파일 경고 아님).
  • Textcube 어댑터(framework/data/Cubrid/Adapter.php)는 $database['driver'] 로 드라이버를 고른다: 'native'(기본, cubrid_* 확장) · 'pdo'(PDO_CUBRID). prepare(php8.2 이상 단계)는 드라이버 바인딩 — native cubrid_prepare/cubrid_bind, pdo PDO::prepare/bindValue(이전의 ? → 리터럴 치환 방식은 폐기). php7.4 단계는 드라이버 선택만. 이 환경에서 패치한 확장으로 실서버 점검 통과. pdo 결과 행은 네이티브와 같은 키 순서(BOTH 는 열마다 번호 키 → 이름 키, 같은 이름·숫자 이름 열은 네이티브처럼 덮어씀)와 NUL 처리(첫 NUL 앞까지)로 다시 짠다(v3.119). PDO 의 FETCH_BOTH 는 이름 키를 먼저 넣고, 문자열 값을 NUL 뒤까지 돌려준다.

확인 결과

CUBRID 11.4.6 서버(cubrid/cubrid:11.4), CCI 11.2, sh cubrid_pdo/run_tests.sh (2026-10-11).

이미지 빌드 경고 native (원본과 diff) smoke persist close lob reuse adapter native adapter pdo
7.4-orig (패치 없음) 0 / 6 기준 OK 57 / FAIL 16 후 세그폴트(139) 2/4 해제된 메모리 접근으로 중단, 잘못된 인자도 true 해제된 메모리 접근으로 중단 영구 연결을 닫은 뒤 해제된 연결 접근으로 중단 원본 트리: cubrid_stat() 없음 Fatal · php7.4 트리 67/67 php7.4 트리 72/72
7.4 0 / 0 생성자 예외의 클래스 이름 표시만 다름(수정) 87/87 4/4 done done done 67/67 72/72
8.2 0 / 0 위 + PHP 코어 Fatal 문구 따옴표 87/87 4/4 done done done 81/81 86/86
8.4 0 / 0 8.2 와 같음 87/87 4/4 done done done 81/81 86/86
8.5 0 / 0 8.2 와 같음 + Fatal 에 스택 추적(8.5 코어) 87/87 4/4 done done done STAGE4 81/81 · 릴리즈본 81/81 STAGE4 86/86 · 릴리즈본 86/86
  • 빌드 경고: cubrid / pdo_cubrid 컴파일러 경고 수(libtool 안내 제외, build_ext.sh 가 이미지 로그 ### … warnings 줄로 집계). dev_compile.sh(-Wall)도 4 버전 모두 0. 7.4-orig pdo_cubrid 6건은 포인터 형식 불일치(스트림 read/write 핸들러의 ssize_t, 드라이버 핸들러 시그니처, zend_hash_update 인자) — 패치에서 수정.
  • adapter: 7.4 단계는 prepare API 가 없어 항목 수가 적다. pdo 는 무작위 SELECT 2000건을 네이티브 결과와 비교(다른 결과 0, 결과가 달라질 문장은 거부 — PHP 8.4 미만 거부 114 중 그대로 실행했으면 실제로 달랐을 문장 6, 8.4 이상 거부 105 중 0). 결과 행 비교(숫자 별칭·같은 이름 열·NUL 값·표 행·queryCell/queryColumn·fetchAllStmt): 수정 전 8.5 pdo 71/86(FAIL 15), 수정 후 전부 통과.
  • close: USE_ZEND_ALLOC=0 으로 실행. 7.4-orig 는 업스트림 cubrid_close_request() 가 변수의 참조까지 놓아 free(): invalid pointer 로 중단, 닫힌 요청·연결·문자열 인자에도 true. 8.5 패치본은 valgrind(-q, adapter 는 -d pcre.jit=0)로 close · lob · reuse · adapter native 모두 오류 0.
  • lob: USE_ZEND_ALLOC=0 으로 실행. 7.4-orig 는 업스트림 LOB 결함(cubrid_lob_get 반환 배열 손상 등)으로 중단 — v3.119 패치본까지 같은 결함, 수정 전후 구간별 결과는 _sectest/_work/cubrid_v3121/results/.
  • reuse: USE_ZEND_ALLOC=0 으로 실행. 7.4-orig 는 영구 연결을 닫은 뒤 요청의 해제된 연결 접근으로 중단 — v3.121 패치본까지 같은 결함 (연결이 닫힌 요청의 NULL 역참조·열 수가 늘어나는 재실행도 중단), 수정 전후 구간별 결과는 _sectest/_work/cubrid_v3122/results/.
  • 7.4-orig smoke FAIL: PDO 생성자 옵션·: ? 든 암호·AUTOCOMMIT 2건·SET 호출자 배열, 네이티브 11건(cubrid_put 호출자 배열 변경·bool→NULL·빈 배열/정수 키 세그폴트·빈 SET 에 앞 속성 값 저장, cubrid_get·cubrid_db_name 호출자 배열 변경, cubrid_fetch_object 클래스 이름이 문자열이 아닐 때 — 정수는 세그폴트(139), 배열은 엉뚱한 크기 할당으로 메모리 한도 Fatal). 끝의 세그폴트는 PDO SET 빈 배열 바인딩(업스트림 결함, 패치본은 정상 실행).
  • 7.4-orig persist: 생성자 옵션 거부로 연결 실패.

About

PHP 8.x PDO/Native connector module for CUBRID, Refer @CUBRID/cubrid-pdo and @CUBRID/cubrid-php, @deokio/textcube-ng

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages