11# SOLAPI PHP SDK
22
3- ** Generated:** 2026-01-21
4- ** Commit:** b68825d
3+ ** Generated:** 2026-01-27
4+ ** Commit:** a27d32f
55** Branch:** master
66
77## OVERVIEW
88
9- PHP SDK for SOLAPI messaging API (SMS, LMS, MMS, Kakao Alimtalk, Voice, Fax) targeting Korean telecom. Zero external dependencies , PHP 7.1+.
9+ PHP SDK for SOLAPI messaging API (SMS, LMS, MMS, Kakao Alimtalk/BMS , Voice, Fax) targeting Korean telecom. PSR-18 HTTP client abstraction , PHP 7.1+.
1010
1111## STRUCTURE
1212
1313```
1414solapi-php/
1515├── src/
1616│ ├── Services/ # Entry point (SolapiMessageService)
17- │ ├── Libraries/ # HTTP client, auth, utilities
17+ │ ├── Libraries/ # HTTP client, auth, utilities (4 files)
1818│ ├── Models/
1919│ │ ├── Request/ # API request DTOs (7 files)
2020│ │ ├── Response/ # API response DTOs (17 files)
21- │ │ ├── Kakao/ # Kakao message options
22- │ │ ├── Voice/ # Voice message options
23- │ │ └── Fax/ # Fax message options
24- │ └── Exceptions/ # Custom exceptions (4 files)
21+ │ │ ├── Kakao/ # Kakao options (4 files)
22+ │ │ │ └── Bms/ # Brand Message Service (14 files) ← See Bms/AGENTS.md
23+ │ │ ├── Voice/ # Voice options (3 files)
24+ │ │ └── Fax/ # Fax options (1 file)
25+ │ └── Exceptions/ # Custom exceptions (5 files)
26+ ├── tests/
27+ │ ├── Models/ # Unit tests
28+ │ └── E2E/ # Integration tests
2529├── composer.json # PSR-4: Nurigo\Solapi\ → src/
26- └── README.md
30+ └── phpunit.xml # Test configuration
2731```
2832
2933## WHERE TO LOOK
@@ -32,13 +36,17 @@ solapi-php/
3236| ------| ----------| -------|
3337| Send messages | ` Services/SolapiMessageService.php ` | Main entry point, all public methods |
3438| Build message | ` Models/Message.php ` | Fluent builder, extends BaseMessage |
35- | HTTP requests | ` Libraries/Fetcher.php ` | Singleton, CURL-based |
39+ | HTTP requests | ` Libraries/Fetcher.php ` | Singleton, PSR-18 client |
3640| Auth header | ` Libraries/Authenticator.php ` | HMAC-SHA256, static method |
37- | Kakao options | ` Models/Kakao/KakaoOption.php ` | pfId, templateId, buttons, bms |
41+ | HTTP transport | ` Libraries/HttpClient.php ` | stream_context-based, PSR-18 compliant |
42+ | Kakao Alimtalk | ` Models/Kakao/KakaoOption.php ` | pfId, templateId, buttons, variables |
43+ | Kakao BMS | ` Models/Kakao/KakaoBms.php ` | Brand messages, 8 chatBubbleTypes |
44+ | BMS validation | ` Models/Kakao/Bms/BmsValidator.php ` | Field requirements by type |
3845| Voice options | ` Models/Voice/VoiceOption.php ` | voiceType, headerMessage, tailMessage |
39- | Error handling | ` Exceptions/ ` | BaseException, CurlException, MessageNotReceivedException |
40- | Request params | ` Models/Request/ ` | SendRequest, GetMessagesRequest, etc. |
41- | Response parsing | ` Models/Response/ ` | SendResponse, GroupMessageResponse, etc. |
46+ | Fax options | ` Models/Fax/FaxOption.php ` | fileIds array |
47+ | Error handling | ` Exceptions/ ` | BaseException, HttpException, BmsValidationException |
48+ | Request DTOs | ` Models/Request/ ` | SendRequest, GetMessagesRequest, etc. |
49+ | Response DTOs | ` Models/Response/ ` | SendResponse, GroupMessageResponse, etc. |
4250
4351## CODE MAP
4452
@@ -50,19 +58,33 @@ $response = $service->send($message);
5058
5159** Call Flow:**
5260```
53- SolapiMessageService → Fetcher (singleton) → Authenticator (static)
54- → CURL → api.solapi.com
55- → Response DTOs
61+ SolapiMessageService
62+ → Fetcher::getInstance() [singleton]
63+ → Authenticator::getAuthorizationHeaderInfo() [static]
64+ → NullEliminator::array_null_eliminate() [static]
65+ → HttpClient::sendRequest() [PSR-18]
66+ → stream_context + file_get_contents
67+ → Response DTOs
5668```
5769
5870** Key Classes:**
5971| Class | Type | Role |
6072| -------| ------| ------|
6173| ` SolapiMessageService ` | Service | Primary API (send, uploadFile, getMessages, getGroups, getBalance) |
62- | ` Message ` | Model | Message builder with fluent setters |
63- | ` Fetcher ` | Library | HTTP client singleton, handles all API requests |
64- | ` Authenticator ` | Library | Generates HMAC-SHA256 auth headers |
65- | ` NullEliminator ` | Library | Removes null values before JSON serialization |
74+ | ` Message ` | Model | Fluent builder with 12 setters |
75+ | ` Fetcher ` | Library | Singleton HTTP client, credential storage |
76+ | ` HttpClient ` | Library | PSR-18 stream-based implementation |
77+ | ` Authenticator ` | Library | HMAC-SHA256 auth header generation |
78+ | ` NullEliminator ` | Library | Recursive null removal for JSON |
79+ | ` BmsValidator ` | Validator | BMS field validation by chatBubbleType |
80+
81+ ** Model Hierarchy:**
82+ ```
83+ BaseMessage → Message (fluent builder)
84+ BaseKakaoOption → KakaoOption (fluent builder)
85+ └── KakaoBms (fluent builder, 8 types)
86+ └── Bms/* components (14 files)
87+ ```
6688
6789## CONVENTIONS
6890
@@ -71,43 +93,61 @@ SolapiMessageService → Fetcher (singleton) → Authenticator (static)
7193** Patterns:**
7294- Fluent builder: ` $msg->setTo("...")->setFrom("...")->setText("...") `
7395- Singleton: ` Fetcher::getInstance($key, $secret) `
74- - Public properties with getters/setters on models
75- - Korean PHPDoc comments (domain-specific )
96+ - Public properties with getter/setter pairs on models
97+ - Korean PHPDoc comments (수신번호, 발신번호, 메시지 내용 )
7698
7799** Type Safety:**
78100- Full type hints on method params/returns
79101- PHPDoc ` @var ` , ` @param ` , ` @return ` , ` @throws ` annotations
102+ - PHP 7.1 compatible (no union types, no enums)
103+
104+ ** Enum-Like Constants:**
105+ - ` VoiceType::FEMALE ` , ` VoiceType::MALE `
106+ - ` BmsChatBubbleType::TEXT ` , ` IMAGE ` , ` WIDE ` , etc.
107+ - All have ` values() ` static method
80108
81109** Tidy First (Kent Beck):**
82110- Separate structural and behavioral changes into distinct commits
83111- Tidy related code before making feature changes
84- - Guard clauses, helper variables/functions, code proximity, symmetry normalization, delete unused code
112+ - Guard clauses, helper variables/functions, code proximity
85113
86114## ANTI-PATTERNS
87115
88- - ** Avoid catch-all nulls :** Many get* methods return ` null ` on any exception — check response validity
89- - ** Singleton state:** Fetcher singleton retains credentials — don't mix different API keys in same process
116+ - ** Silent null returns :** get* methods return ` null ` on any exception — always check response validity
117+ - ** Singleton state:** Fetcher retains credentials — don't mix API keys in same process
90118- ** No interfaces:** Service/Fetcher have no contracts — mocking requires concrete class extension
91- - ** SSL verification disabled:** ` CURLOPT_SSL_VERIFYPEER = false ` in Fetcher
119+ - ** Hardcoded timezone:** ` Asia/Seoul ` set in Authenticator — affects global timezone
120+ - ** Hardcoded country:** ` "82" ` default in BaseMessage — Korean-only by default
92121
93122## UNIQUE STYLES
94123
95- - ** Korean comments:** PHPDoc descriptions in Korean (수신번호, 발신번호, 메시지 내용)
96- - ** Default country :** ` "82" ` (Korea) hardcoded in BaseMessage
97- - ** Timezone :** ` Asia/Seoul ` set in Authenticator
124+ - ** Korean comments:** PHPDoc descriptions in Korean
125+ - ** PSR-18 via stream :** Uses ` file_get_contents ` + ` stream_context_create ` , not cURL
126+ - ** Null elimination :** Removes nulls before JSON serialization
98127
99128## COMMANDS
100129
101130``` bash
102131# Install
103132composer require solapi/sdk
104133
105- # No local tests — see solapi-php-examples repo
134+ # Run all tests
135+ composer test
136+
137+ # Run unit tests only
138+ composer test:unit
139+
140+ # Run E2E tests only
141+ composer test:e2e
142+
143+ # Run with coverage
144+ composer test:coverage
106145```
107146
108147## NOTES
109148
110149- ** Examples:** External repo at ` github.com/solapi/solapi-php-examples `
111150- ** API docs:** ` developers.solapi.com `
112- - ** PHP requirement:** 7.1+ (ext-curl, ext-json required)
113- - ** TODO in README:** Missing documentation link (line 19)
151+ - ** PHP requirement:** 7.1+ (ext-json, allow_url_fopen or custom PSR-18 client)
152+ - ** Dependencies:** psr/http-client, psr/http-message, nyholm/psr7
153+ - ** BMS details:** See ` src/Models/Kakao/Bms/AGENTS.md ` for Brand Message Service specifics
0 commit comments