CodeSampleX

샘플

doctrine/dbal 4.4.4: Query an in-memory SQLite through Doctrine DBAL 4 without the parameter binding, empty result and schema introspection traps

검증된 샘플 — composer doctrine/dbal 4.4.4: Query an in-memory SQLite through Doctrine DBAL 4 without the parameter binding, empty result and schema introspection…

sha256:090b8a4df8ed4282fa66e190d2a7e4a2c1611b82a538304c73a2585e29fa9c7a

이 네트워크가 제공하는 것은 하나입니다. 빌드되는 샘플. 샌드박스에서 돌리고 서명된 영수증을 보관합니다. 등급을 매기지 않고 무엇도 보증하지 않습니다 — 같은 코드가 당신 환경에서 빌드되는지는 측정한 적이 없습니다. 통과한 계약 영수증을 낸 서로 다른 서명 키의 수입니다. 하나면 작성자 혼자이고, 둘 이상이면 다른 사람도 빌드했다는 뜻입니다. 키는 스스로 만드는 것이고 뒤에 등록된 신원이 없으므로, 세는 것은 사람이 아니라 키입니다. MIT-0

실행 증거

선언된 환경과 서명된 실행을 분리해 두었습니다. 이 샘플이 무엇을 어디서 실행했는지 그대로 볼 수 있습니다.

증거 기준
서명된 컨트랙트 통과
검증 영수증
1
빌드한 서명 키
1
선언된 환경 php 8 linux x64 php 8 php composer

검증 실행 환경

환경 컨트랙트 단계 실행일
php 8 · linux alpine/x64 · docker ed25519:a2ec939a4c60e243 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · composer@1
2026-08-14

케이스

HOW
목표
Query an in-memory SQLite through Doctrine DBAL 4 without the parameter binding, empty result and schema introspection traps
패키지
심벌
  • Doctrine.DBAL.DriverManager
  • Connection::executeQuery
  • Result::fetchAssociative
  • Doctrine.DBAL.ParameterType
  • Doctrine.DBAL.ArrayParameterType
  • QueryBuilder::createNamedParameter
  • QueryBuilder::setParameter
  • AbstractSchemaManager::introspectTable
  • Type::lookupName
환경
php 8
생성일
2026-08-14T20:22:50Z

컨트랙트

  1. assert positional parameters are bound in the order the array was built and never by its keys, so two arrays that are == with the same keys give different answers and ksort alone changes the result
  2. assert named parameters are resolved by name so the order they were set in cannot matter, and that a 1-based or nonsense-keyed positional array still works because no key is ever read
  3. assert named and positional placeholders can be mixed in one statement despite the manual saying they cannot, and that whether the SQL parser runs at all is decided by is_string on the first key of the params array
  4. assert that same switch decides whether a bad parameter list raises MissingNamedParameter or MissingPositionalParameter or instead reaches the driver as SQLSTATE column index out of range, and that a surplus named value is silently unused
  5. assert fetchAssociative returns false rather than null when the result is exhausted so the ?? guard never fires, and that fetchOne returns false for no row but int 0 for a stored zero, which are == but not ===
  6. assert fetchAllAssociative spells the same emptiness as an empty array instead, and that rowCount reports 0 for a SELECT on pdo_sqlite so counting has to happen in SQL
  7. assert a wrong ParameterType rewrites the value instead of failing: '0012' bound as INTEGER is stored as '12', 'abc' becomes 0, 2.9 truncates to 2, and false bound as STRING becomes the empty string rather than '0'
  8. assert that mistake still matches on an INTEGER column because SQLite applies column affinity to the comparison, and matches nothing against a text column, which is why it survives the read path and only corrupts writes
  9. assert an IN clause needs createNamedParameter with an ArrayParameterType, that the single placeholder is expanded into one ? per element inside executeQuery rather than by the builder, and that an empty list becomes the literal NULL
  10. assert expr()->in with a raw array interpolates the values into the SQL and dies on 'no such column' for strings, that setParameter with an array and the default type only raises a PHP 'Array to string conversion' warning and matches nothing, and that a scalar ParameterType casts the array to 1 with no diagnostic at all
  11. assert setParameter binds a value without adding a placeholder, so a parameter whose placeholder is missing from the SQL is discarded without complaint
  12. assert schema introspection returns datetime for datetime_immutable, text for json and simple_array, and a fixed string(36) for guid, while length, precision, scale and autoincrement do survive the round trip
  13. assert the Comparator still calls the two schemas identical and emits no ALTER because it compares the generated DDL rather than the Doctrine type, so the loss surfaces only in convertToPHPValue handing back a mutable DateTime and an undecoded JSON string
  14. assert introspecting a declared type with no mapping raises InvalidArgumentException instead of falling back to string, and that Type::getName is gone in DBAL 4 in favour of the static Type::lookupName

파일

  • composer.json
  • composer.lock
  • csx.json
  • phpunit.xml
  • src/Ledger.php
  • test/LedgerTest.php

소스 아티팩트 내려받기 (tar.gz)

오리진 시더

anonymous