Skip to content

Commit da0c91d

Browse files
committed
add example: class.
1 parent 9ebd055 commit da0c91d

File tree

19 files changed

+318
-60
lines changed

19 files changed

+318
-60
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ members = [
88

99
# internal
1010
"examples/simple",
11+
"examples/class",
1112
]

examples/class/Cargo.toml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[package]
2+
name = "class"
3+
version = "0.2.0"
4+
authors = ["jmjoy <[email protected]>"]
5+
edition = "2018"
6+
publish = false
7+
8+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
9+
10+
[lib]
11+
crate-type = ["cdylib"]
12+
13+
[dependencies]
14+
phper = { version = "0.2", path = "../../phper" }
15+
16+
[build-dependencies]
17+
phper-build = { version = "0.2", path = "../../phper-build" }

examples/class/Makefile.toml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
[env]
2+
PHP_CONFIG = "php-config"
3+
TARGET_DIR = "${CARGO_MAKE_WORKING_DIRECTORY}/../../target"
4+
5+
[env.development]
6+
TARGET_BUILD_DIR = "${TARGET_DIR}/debug"
7+
8+
[env.production]
9+
TARGET_BUILD_DIR = "${TARGET_DIR}/release"
10+
11+
[tasks.install]
12+
dependencies = ["build"]
13+
script = [
14+
"""
15+
cp ${TARGET_BUILD_DIR}/lib${CARGO_MAKE_CRATE_NAME}.so `${PHP_CONFIG} --extension-dir`/${CARGO_MAKE_CRATE_NAME}.so && \
16+
echo Installing shared extensions: `${PHP_CONFIG} --extension-dir`
17+
"""
18+
]
19+
20+
[tasks.test-php]
21+
script = [
22+
"`${PHP_CONFIG} --php-binary` tests/confirm_compiled.php"
23+
]
24+
25+
[tasks.test-all]
26+
dependencies = [
27+
"install",
28+
"test",
29+
"test-php",
30+
]

examples/class/build.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
phper_build::register_configures();
3+
}

examples/class/src/lib.rs

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
#![feature(allocator_api)]
2+
3+
use phper::{c_str_ptr, php_fn, ebox};
4+
use phper::sys::{ZEND_RESULT_CODE_SUCCESS, zend_parse_parameters, zend_internal_arg_info, zend_function_entry, PHP_INI_SYSTEM, ZEND_ACC_PUBLIC};
5+
use phper::sys::{zend_ini_entry_def, zend_module_entry, zend_register_ini_entries, zend_unregister_ini_entries, zend_class_entry};
6+
use phper::zend::api::FunctionEntries;
7+
use phper::zend::compile::InternalArgInfos;
8+
use phper::zend::ini::IniEntryDefs;
9+
use phper::zend::modules::ModuleEntry;
10+
use phper::zend::types::{ExecuteData, Val};
11+
use phper::{
12+
php_function, php_minit, php_minit_function, php_mshutdown, php_mshutdown_function,
13+
php_rinit_function, php_rshutdown_function,
14+
};
15+
use phper::{php_minfo, php_minfo_function, php_rinit, php_rshutdown, zend_get_module};
16+
use std::ffi::{CStr, CString};
17+
use std::mem;
18+
use std::mem::{size_of, transmute, MaybeUninit, size_of_val, zeroed};
19+
use std::os::raw::{c_char, c_int, c_uchar, c_uint, c_ushort};
20+
use std::ptr::{null, null_mut};
21+
use phper::sys::{zend_string, zend_register_internal_class_ex, phper_init_class_entry, zend_register_internal_class, phper_zval_string};
22+
use phper::sys::{zend_declare_property_string, zend_type, zend_read_property};
23+
24+
static mut MY_CLASS_CE: *mut zend_class_entry = null_mut();
25+
26+
static INI_ENTRIES: IniEntryDefs<1> = IniEntryDefs::new([
27+
unsafe { transmute([0u8; size_of::<zend_ini_entry_def>()]) },
28+
]);
29+
30+
static ARG_INFO_MY_CLASS_FOO: InternalArgInfos<2> = InternalArgInfos::new([
31+
zend_internal_arg_info {
32+
name: 2 as *const _,
33+
type_: 0,
34+
pass_by_reference: 0,
35+
is_variadic: 0,
36+
},
37+
zend_internal_arg_info {
38+
name: c_str_ptr!("prefix"),
39+
type_: 0,
40+
pass_by_reference: 0,
41+
is_variadic: 0,
42+
},
43+
]);
44+
45+
static MY_CLASS_METHODS: FunctionEntries<2> = FunctionEntries::new([
46+
zend_function_entry {
47+
fname: c_str_ptr!("foo"),
48+
handler: Some(php_fn!(my_class_foo)),
49+
arg_info: ARG_INFO_MY_CLASS_FOO.get(),
50+
num_args: 1,
51+
flags: 0,
52+
},
53+
unsafe { transmute([0u8; size_of::<zend_function_entry>()]) },
54+
]);
55+
56+
57+
#[php_function]
58+
pub fn my_class_foo(execute_data: ExecuteData, return_value: Val) {
59+
let mut prefix: *const c_char = null_mut();
60+
let mut prefix_len = 0;
61+
62+
unsafe {
63+
if zend_parse_parameters(
64+
execute_data.num_args() as c_int,
65+
c_str_ptr!("s"),
66+
&mut prefix,
67+
&mut prefix_len,
68+
) != ZEND_RESULT_CODE_SUCCESS
69+
{
70+
return;
71+
}
72+
73+
let prefix = CStr::from_ptr(prefix).to_str().unwrap();
74+
75+
let this = if execute_data.get_type() == phper::sys::IS_OBJECT as zend_type {
76+
execute_data.get_this()
77+
} else {
78+
null_mut()
79+
};
80+
81+
let foo = zend_read_property(MY_CLASS_CE, this, c_str_ptr!("foo"), 3, 1, null_mut());
82+
let foo = Val::from_raw(foo);
83+
let foo = foo.as_c_str().unwrap().to_str().unwrap();
84+
let s = CString::new(&*format!("{}{}", prefix, foo)).unwrap();
85+
86+
phper_zval_string(return_value.get(), s.as_ptr());
87+
}
88+
}
89+
90+
#[php_minit_function]
91+
fn m_init_simple(type_: c_int, module_number: c_int) -> bool {
92+
unsafe {
93+
zend_register_ini_entries(INI_ENTRIES.get(), module_number);
94+
}
95+
96+
unsafe {
97+
let mut my_class_ce = phper_init_class_entry(c_str_ptr!("MyClass"), MY_CLASS_METHODS.get());
98+
MY_CLASS_CE = zend_register_internal_class(&mut my_class_ce);
99+
zend_declare_property_string(MY_CLASS_CE, c_str_ptr!("foo"), 3, c_str_ptr!("bar"), ZEND_ACC_PUBLIC as c_int);
100+
}
101+
102+
true
103+
}
104+
105+
#[php_mshutdown_function]
106+
fn m_shutdown_simple(type_: c_int, module_number: c_int) -> bool {
107+
unsafe {
108+
zend_unregister_ini_entries(module_number);
109+
}
110+
true
111+
}
112+
113+
#[php_rinit_function]
114+
fn r_init_simple(type_: c_int, module_number: c_int) -> bool {
115+
true
116+
}
117+
118+
#[php_rshutdown_function]
119+
fn r_shutdown_simple(type_: c_int, module_number: c_int) -> bool {
120+
true
121+
}
122+
123+
#[php_minfo_function]
124+
fn m_info_simple(zend_module: *mut ::phper::sys::zend_module_entry) {
125+
}
126+
127+
static MODULE_ENTRY: ModuleEntry = ModuleEntry::new(zend_module_entry {
128+
size: size_of::<zend_module_entry>() as c_ushort,
129+
zend_api: phper::sys::ZEND_MODULE_API_NO as c_uint,
130+
zend_debug: phper::sys::ZEND_DEBUG as c_uchar,
131+
zts: phper::sys::USING_ZTS as c_uchar,
132+
ini_entry: std::ptr::null(),
133+
deps: std::ptr::null(),
134+
name: c_str_ptr!(env!("CARGO_PKG_NAME")),
135+
functions: null(),
136+
module_startup_func: Some(php_minit!(m_init_simple)),
137+
module_shutdown_func: Some(php_mshutdown!(m_shutdown_simple)),
138+
request_startup_func: Some(php_rinit!(r_init_simple)),
139+
request_shutdown_func: Some(php_rshutdown!(r_shutdown_simple)),
140+
info_func: Some(php_minfo!(m_info_simple)),
141+
version: c_str_ptr!(env!("CARGO_PKG_VERSION")),
142+
globals_size: 0usize,
143+
#[cfg(phper_zts)]
144+
globals_id_ptr: std::ptr::null_mut(),
145+
#[cfg(not(phper_zts))]
146+
globals_ptr: std::ptr::null_mut(),
147+
globals_ctor: None,
148+
globals_dtor: None,
149+
post_deactivate_func: None,
150+
module_started: 0,
151+
type_: 0,
152+
handle: null_mut(),
153+
module_number: 0,
154+
build_id: phper::sys::PHP_MODULE_BUILD_ID,
155+
});
156+
157+
#[zend_get_module]
158+
pub fn get_module() -> &'static ModuleEntry {
159+
&MODULE_ENTRY
160+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
ini_set("display_errors", "On");
4+
ini_set("display_startup_errors", "On");
5+
error_reporting(E_ALL);
6+
7+
var_dump((new MyClass())->foo("foo-"));

examples/simple/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ publish = false
88
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
99

1010
[lib]
11-
name = "simple"
1211
crate-type = ["cdylib"]
1312

1413
[dependencies]

examples/simple/Makefile.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ script = [
2424

2525
[tasks.test-all]
2626
dependencies = [
27+
"install",
2728
"test",
2829
"test-php",
2930
]

examples/simple/src/lib.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
use phper::c_str_ptr;
2-
use phper::php_fn;
1+
#![feature(allocator_api)]
2+
3+
use phper::{c_str_ptr, php_fn, ebox};
34
use phper::sys::{ZEND_RESULT_CODE_SUCCESS, zend_parse_parameters, zend_internal_arg_info, zend_function_entry, PHP_INI_SYSTEM};
45
use phper::sys::{zend_ini_entry_def, zend_module_entry, zend_register_ini_entries, zend_unregister_ini_entries};
56
use phper::zend::api::FunctionEntries;
@@ -36,7 +37,6 @@ static INI_ENTRIES: IniEntryDefs<2> = IniEntryDefs::new([
3637

3738
#[php_minit_function]
3839
fn m_init_simple(type_: c_int, module_number: c_int) -> bool {
39-
println!("module init");
4040
unsafe {
4141
zend_register_ini_entries(INI_ENTRIES.get(), module_number);
4242
}
@@ -45,7 +45,6 @@ fn m_init_simple(type_: c_int, module_number: c_int) -> bool {
4545

4646
#[php_mshutdown_function]
4747
fn m_shutdown_simple(type_: c_int, module_number: c_int) -> bool {
48-
println!("module shutdown");
4948
unsafe {
5049
zend_unregister_ini_entries(module_number);
5150
}
@@ -54,19 +53,16 @@ fn m_shutdown_simple(type_: c_int, module_number: c_int) -> bool {
5453

5554
#[php_rinit_function]
5655
fn r_init_simple(type_: c_int, module_number: c_int) -> bool {
57-
println!("request init");
5856
true
5957
}
6058

6159
#[php_rshutdown_function]
6260
fn r_shutdown_simple(type_: c_int, module_number: c_int) -> bool {
63-
println!("request shutdown");
6461
true
6562
}
6663

6764
#[php_minfo_function]
6865
fn m_info_simple(zend_module: *mut ::phper::sys::zend_module_entry) {
69-
println!("info init");
7066
}
7167

7268
#[php_function]
@@ -130,7 +126,7 @@ pub fn get_module() -> &'static ModuleEntry {
130126
fname: c_str_ptr!("test_simple"),
131127
handler: Some(php_fn!(test_simple)),
132128
arg_info: ARG_INFO_TEST_SIMPLE.get(),
133-
num_args: 0,
129+
num_args: 2,
134130
flags: 0,
135131
},
136132
unsafe { transmute([0u8; size_of::<zend_function_entry>()]) },

phper-alloc/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub struct Allocator {
1919
}
2020

2121
impl Allocator {
22-
pub fn new(
22+
pub const fn new(
2323
#[cfg(phper_debug)]
2424
zend_filename: *const c_char,
2525
#[cfg(phper_debug)]

0 commit comments

Comments
 (0)