Skip to content

Commit 90cc532

Browse files
committed
Rename Rust library from php-node to php
Rename the Rust crate and library from php-node/php_node to php for better clarity and consistency. Updated all references throughout the codebase including doctests. Changes: - Cargo.toml: Changed package name from 'php-node' to 'php' - Cargo.toml: Changed lib name from 'php_node' to 'php' - src/lib.rs: Updated doctest to use 'php::' instead of 'php_node::' - src/embed.rs: Updated all doctests to use 'php::' prefix - src/main.rs: Updated imports to use 'php::' prefix - CLAUDE.md: Updated documentation to reflect single-crate structure and removed references to old multi-crate workspace All tests pass with the new naming.
1 parent 3168f2e commit 90cc532

File tree

7 files changed

+80
-149
lines changed

7 files changed

+80
-149
lines changed

CLAUDE.md

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,21 @@ npm run version
3737
# Build with proper rpath for linking libphp
3838
RUSTFLAGS="-C link-args=-Wl,-rpath,\$ORIGIN" npm run build
3939

40-
# Build specific crate
41-
cargo build --manifest-path crates/php_node/Cargo.toml --release
40+
# Run Rust tests
41+
cargo test
42+
43+
# Run binary directly
44+
cargo run
4245
```
4346

4447
## Architecture
4548

4649
### Multi-language Structure
47-
- **Rust** (`/crates`): Core implementation using Cargo workspace
48-
- `lang_handler`: Generic language handler abstractions
49-
- `php`: PHP embedding and SAPI implementation
50-
- `php_node`: NAPI bindings exposing Rust to Node.js
50+
- **Rust** (`/src`): Single-crate implementation
51+
- PHP embedding and SAPI implementation
52+
- NAPI bindings exposing Rust to Node.js (when `napi-support` feature is enabled)
53+
- Binary target for standalone testing (`src/main.rs`)
54+
- Library target for NAPI usage (`src/lib.rs`)
5155
- **JavaScript**: Node.js API layer (`index.js`, `index.d.ts`)
5256
- **PHP**: Embedded runtime via libphp.{so,dylib}
5357

@@ -87,21 +91,22 @@ cargo build --manifest-path crates/php_node/Cargo.toml --release
8791

8892
5. **Platform Support**: x64 Linux, x64/arm64 macOS (pre-built binaries in `/npm`)
8993

90-
6. **Recent Architecture Changes**:
91-
- `lang_handler` crate no longer uses `napi` features directly (removed from dependencies)
92-
- `php` crate uses custom fork of ext-php-rs from platformatic GitHub org
94+
6. **Recent Architecture Changes**:
95+
- Consolidated from multi-crate workspace to single crate named `php`
96+
- NAPI support is now feature-gated with `napi-support` feature
97+
- Binary target supports both library (`rlib`) and dynamic library (`cdylib`) outputs
9398

9499
## Common Tasks
95100

96101
### Adding New NAPI Functions
97-
1. Implement in Rust under `crates/php_node/src/`
102+
1. Implement in Rust under `src/` with `#[cfg(feature = "napi-support")]`
98103
2. Use `#[napi]` attributes for exposed functions/classes
99104
3. Run `npm run build` to regenerate TypeScript definitions
100105

101106
### Modifying Request/Response Handling
102-
- Core logic in `crates/php/src/sapi.rs`
107+
- Core logic in `src/sapi.rs` and `src/embed.rs`
103108
- JavaScript wrapper in `index.js`
104-
- Headers handling in `crates/php_node/src/headers.rs`
109+
- Request/response types from `http-handler` crate
105110

106111
### Debugging PHP Issues
107112
- Check INTERNALS.md for PHP embedding details
@@ -118,7 +123,9 @@ The rewriter system supports Apache mod_rewrite-like functionality:
118123
## Project Files Reference
119124

120125
- `index.js`: Main JavaScript API, exports PHP, Request, Response, Headers, Rewriter classes
121-
- `crates/php_node/src/lib.rs`: NAPI bindings entry point
122-
- `crates/php/src/sapi.rs`: PHP SAPI implementation (core request handling)
123-
- `crates/lang_handler/src/`: Generic language handler abstractions (request/response/rewriter)
126+
- `src/lib.rs`: Library entry point, exports core types and NAPI bindings
127+
- `src/main.rs`: Binary entry point for standalone testing
128+
- `src/embed.rs`: Core `Embed` type for handling PHP requests
129+
- `src/sapi.rs`: PHP SAPI implementation (low-level PHP integration)
130+
- `src/runtime.rs`: NAPI runtime implementation (when `napi-support` feature enabled)
124131
- `__test__/*.spec.mjs`: Test files for each component

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
edition = "2021"
3-
name = "php-node"
3+
name = "php"
44
version = "1.4.0"
55
authors = ["Platformatic Inc. <[email protected]> (https://platformatic.dev)"]
66
license = "MIT"
@@ -11,7 +11,7 @@ default = []
1111
napi-support = ["dep:napi", "dep:napi-derive", "dep:napi-build", "http-handler/napi-support", "http-rewriter/napi-support"]
1212

1313
[lib]
14-
name = "php_node"
14+
name = "php"
1515
crate-type = ["cdylib", "rlib"]
1616
path = "src/lib.rs"
1717

@@ -26,7 +26,7 @@ hostname = "0.4.1"
2626
ext-php-rs = { version = "0.14.0", features = ["embed"] }
2727
http-handler = { git = "https://github.com/platformatic/http-handler.git" }
2828
# http-handler = { path = "../http-handler" }
29-
http-rewriter = { git = "https://github.com/platformatic/http-rewriter.git", branch = "add-docroot-parameter-support" }
29+
http-rewriter = { git = "https://github.com/platformatic/http-rewriter.git" }
3030
# http-rewriter = { path = "../http-rewriter" }
3131
libc = "0.2.171"
3232
# Default enable napi4 feature, see https://nodejs.org/api/n-api.html#node-api-version-matrix

src/embed.rs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use ext_php_rs::{
1212
zend::{try_catch, try_catch_first, ExecutorGlobals, SapiGlobals},
1313
};
1414

15-
use http_handler::{Handler, Request, Response};
15+
use http_handler::{Handler, Request, Response, ResponseBuilderExt};
1616

1717
use super::{
1818
sapi::{ensure_sapi, Sapi},
@@ -90,7 +90,7 @@ impl Embed {
9090
///
9191
/// ```
9292
/// use std::env::current_dir;
93-
/// use php_node::Embed;
93+
/// use php::Embed;
9494
///
9595
/// let docroot = current_dir()
9696
/// .expect("should have current_dir");
@@ -113,7 +113,7 @@ impl Embed {
113113
///
114114
/// ```
115115
/// use std::env::{args, current_dir};
116-
/// use php_node::Embed;
116+
/// use php::Embed;
117117
///
118118
/// let docroot = current_dir()
119119
/// .expect("should have current_dir");
@@ -137,7 +137,7 @@ impl Embed {
137137
///
138138
/// ```
139139
/// use std::env::current_dir;
140-
/// use php_node::{Embed, Handler, Request, Response};
140+
/// use php::{Embed, Handler, Request, Response};
141141
///
142142
/// let docroot = current_dir()
143143
/// .expect("should have current_dir");
@@ -174,7 +174,7 @@ impl Embed {
174174
///
175175
/// ```rust
176176
/// use std::env::current_dir;
177-
/// use php_node::Embed;
177+
/// use php::Embed;
178178
///
179179
/// let docroot = current_dir()
180180
/// .expect("should have current_dir");
@@ -199,7 +199,7 @@ impl Handler for Embed {
199199
///
200200
/// ```
201201
/// use std::{env::temp_dir, fs::File, io::Write};
202-
/// use php_node::{Embed, Handler, Request, Response, MockRoot};
202+
/// use php::{Embed, Handler, Request, Response, MockRoot};
203203
///
204204
/// let docroot = MockRoot::builder()
205205
/// .file("index.php", "<?php echo \"Hello, World!\"; ?>")
@@ -321,10 +321,10 @@ impl Handler for Embed {
321321

322322
let ex = Error::Exception(err);
323323

324-
// Fixed exception handling (FIXME.md #3) by using ResponseExt::set_exception
325324
if let Some(ctx) = RequestContext::current() {
326-
ctx.set_response_exception(ex.to_string());
327-
ctx.set_response_status(500);
325+
let builder = std::mem::replace(ctx.response_builder_mut(), http_handler::response::Builder::new());
326+
let builder = builder.exception(ex.to_string()).status(500);
327+
*ctx.response_builder_mut() = builder;
328328
}
329329

330330
return Err(EmbedRequestError::Exception(ex.to_string()));
@@ -351,10 +351,13 @@ impl Handler for Embed {
351351
efree(mimetype.cast::<u8>());
352352
}
353353

354-
// Set the final status and content-type header using the new clean API (FIXME.md #4)
354+
// Set the final status and content-type header
355355
if let Some(ctx) = RequestContext::current() {
356-
ctx.set_response_status(http_response_code as u16);
357-
ctx.add_response_header("Content-Type", mime);
356+
let builder = std::mem::replace(ctx.response_builder_mut(), http_handler::response::Builder::new());
357+
let builder = builder
358+
.status(http_response_code as u16)
359+
.header("Content-Type", mime);
360+
*ctx.response_builder_mut() = builder;
358361
}
359362

360363
// Build the final response with accumulated data using the extension system

src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
//! ```rust
99
//! use std::env::{args, current_dir};
1010
//! # use std::path::PathBuf;
11-
//! # use php_node::MockRoot;
12-
//! use php_node::{
11+
//! # use php::MockRoot;
12+
//! use php::{
1313
//! rewrite::{PathRewriter, Rewriter},
1414
//! Embed, Handler, Request,
1515
//! };

src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::{env::current_dir, fs::File, io::Write, path::PathBuf};
22

33
use bytes::BytesMut;
4-
use php_node::{rewrite::PathRewriter, Embed, Handler, Request, RequestRewriter};
4+
use php::{rewrite::PathRewriter, Embed, Handler, Request, RequestRewriter};
55

66
#[tokio::main]
77
async fn main() {

src/request_context.rs

Lines changed: 19 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,23 @@
1-
use bytes::BytesMut;
21
use ext_php_rs::zend::SapiGlobals;
3-
use http_handler::request::Parts;
4-
use http_handler::{
5-
BodyBuffer, HeaderMap, HeaderName, HeaderValue, Request, ResponseBuilderExt, ResponseLog,
6-
StatusCode,
7-
};
2+
use http_handler::{BodyBuffer, Request};
83
use std::{ffi::c_void, path::PathBuf};
94

105
/// The request context for the PHP SAPI.
11-
///
12-
/// This has been redesigned to address all issues in FIXME.md:
13-
/// - Uses request Parts to avoid RefUnwindSafe issues (#1)
14-
/// - Stores mutable body for proper consumption (#2)
15-
/// - Uses extension types to accumulate response data (#3, #4)
16-
#[derive(Debug)]
176
pub struct RequestContext {
18-
request_parts: Parts,
19-
request_body: BytesMut,
20-
response_status: StatusCode,
21-
response_headers: HeaderMap,
22-
response_body: BodyBuffer,
23-
response_log: ResponseLog,
24-
response_exception: Option<String>,
7+
request: Request,
8+
response_builder: http_handler::response::Builder,
259
docroot: PathBuf,
2610
}
2711

2812
impl RequestContext {
2913
/// Sets the current request context for the PHP SAPI.
30-
///
31-
/// Uses into_parts() to avoid RefUnwindSafe issues (FIXME.md #1).
3214
pub fn for_request<S>(request: Request, docroot: S)
3315
where
3416
S: Into<PathBuf>,
3517
{
36-
// Use into_parts() to avoid RefUnwindSafe issues (FIXME.md #1)
37-
let (parts, body) = request.into_parts();
38-
3918
let context = Box::new(RequestContext {
40-
request_parts: parts,
41-
request_body: body,
42-
response_status: StatusCode::OK,
43-
response_headers: HeaderMap::new(),
44-
response_body: BodyBuffer::new(),
45-
response_log: ResponseLog::new(),
46-
response_exception: None,
19+
request,
20+
response_builder: http_handler::response::Builder::new(),
4721
docroot: docroot.into(),
4822
});
4923
let mut globals = SapiGlobals::get_mut();
@@ -76,86 +50,32 @@ impl RequestContext {
7650
Some(unsafe { Box::from_raw(ptr as *mut RequestContext) })
7751
}
7852

79-
/// Returns a reference to the request parts.
80-
/// This replaces the old request() method since we now use parts.
81-
pub fn request_parts(&self) -> &Parts {
82-
&self.request_parts
83-
}
84-
85-
/// Returns a mutable reference to the request body.
86-
/// This allows proper consumption of the body (FIXME.md #2).
87-
pub fn request_body_mut(&mut self) -> &mut BytesMut {
88-
&mut self.request_body
53+
/// Returns a reference to the request.
54+
pub fn request(&self) -> &Request {
55+
&self.request
8956
}
9057

91-
/// Returns a reference to the request body.
92-
pub fn request_body(&self) -> &BytesMut {
93-
&self.request_body
94-
}
95-
96-
/// Add a header to the response.
97-
pub fn add_response_header<K, V>(&mut self, key: K, value: V)
98-
where
99-
K: TryInto<HeaderName>,
100-
V: TryInto<HeaderValue>,
101-
{
102-
if let (Ok(header_name), Ok(header_value)) = (key.try_into(), value.try_into()) {
103-
self.response_headers.insert(header_name, header_value);
104-
}
105-
}
106-
107-
/// Set the response status code.
108-
pub fn set_response_status(&mut self, status: u16) {
109-
if let Ok(status_code) = StatusCode::from_u16(status) {
110-
self.response_status = status_code;
111-
}
58+
/// Returns a mutable reference to the request.
59+
pub fn request_mut(&mut self) -> &mut Request {
60+
&mut self.request
11261
}
11362

114-
/// Write data to the response body.
115-
pub fn write_response_body(&mut self, data: &[u8]) {
116-
self.response_body.append(data);
117-
}
118-
119-
/// Write to the response log.
120-
/// This uses extension types to accumulate log data (FIXME.md #4).
121-
pub fn write_response_log(&mut self, data: &[u8]) {
122-
self.response_log.append(data);
123-
}
124-
125-
/// Set an exception on the response.
126-
/// This stores the exception to be added via ResponseBuilderExt (FIXME.md #3).
127-
pub fn set_response_exception(&mut self, exception: impl Into<String>) {
128-
self.response_exception = Some(exception.into());
63+
/// Returns a mutable reference to the response builder.
64+
pub fn response_builder_mut(&mut self) -> &mut http_handler::response::Builder {
65+
&mut self.response_builder
12966
}
13067

13168
/// Build the final response using the accumulated data.
132-
/// This properly uses ResponseBuilderExt for logs and exceptions (FIXME.md #3, #4).
133-
pub fn build_response(self) -> Result<http_handler::Response, http_handler::Error> {
134-
// Start building the response
135-
let mut builder = http_handler::response::Response::builder().status(self.response_status);
136-
137-
// Add all headers
138-
for (key, value) in &self.response_headers {
139-
builder = builder.header(key, value);
140-
}
141-
142-
// Add extensions using ResponseBuilderExt
143-
builder = builder
144-
.body_buffer(self.response_body)
145-
.log(self.response_log.into_bytes());
146-
147-
if let Some(exception) = self.response_exception {
148-
builder = builder.exception(exception);
149-
}
150-
151-
// Get the body buffer from extensions and build final response
152-
let body = builder
69+
pub fn build_response(mut self) -> Result<http_handler::Response, http_handler::Error> {
70+
// Extract the body buffer from extensions (if any was accumulated)
71+
let body = self
72+
.response_builder
15373
.extensions_mut()
15474
.and_then(|ext| ext.remove::<BodyBuffer>())
15575
.unwrap_or_default()
15676
.into_bytes_mut();
15777

158-
builder.body(body)
78+
self.response_builder.body(body)
15979
}
16080

16181
/// Returns the docroot associated with this request context

0 commit comments

Comments
 (0)