Skip to content

Commit 2100e54

Browse files
committed
Example mini-curl: add method exec.
1 parent 51bd691 commit 2100e54

File tree

8 files changed

+80
-14
lines changed

8 files changed

+80
-14
lines changed

examples/mini-curl/src/lib.rs

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
use curl::easy::Easy;
22
use phper::{
3-
c_str_ptr, php_fn, php_function, php_minfo, php_minfo_function, php_minit, php_minit_function,
3+
c_str_ptr,
4+
main::php::error_doc_ref,
5+
php_fn, php_function, php_minfo, php_minfo_function, php_minit, php_minit_function,
46
php_mshutdown, php_mshutdown_function, php_rinit, php_rinit_function, php_rshutdown,
57
php_rshutdown_function,
6-
sys::{
7-
php_error_docref0, php_info_print_table_end, php_info_print_table_start, E_WARNING,
8-
PHP_INI_SYSTEM,
9-
},
8+
sys::{php_info_print_table_end, php_info_print_table_start, PHP_INI_SYSTEM},
109
zend::{
1110
api::{FunctionEntries, FunctionEntryBuilder},
1211
compile::{create_zend_arg_info, MultiInternalArgInfo, Visibility},
12+
errors::Level,
1313
ini::{create_ini_entry, IniEntries},
1414
modules::{create_zend_module_entry, ModuleArgs, ModuleEntry},
1515
types::{ClassEntry, ExecuteData, ReturnValue, SetVal, Value},
@@ -60,7 +60,7 @@ static ARG_INFO_VOID: MultiInternalArgInfo<0> = MultiInternalArgInfo::new(0, fal
6060
static ARG_INFO_MINI_CURL_CONSTRUCT: MultiInternalArgInfo<1> =
6161
MultiInternalArgInfo::new(0, false, [create_zend_arg_info(c_str_ptr!("url"), false)]);
6262

63-
static MINI_CURL_METHODS: FunctionEntries<2> = FunctionEntries::new([
63+
static MINI_CURL_METHODS: FunctionEntries<3> = FunctionEntries::new([
6464
FunctionEntryBuilder::new(
6565
c_str_ptr!("__construct"),
6666
Some(php_fn!(mini_curl_construct)),
@@ -70,6 +70,9 @@ static MINI_CURL_METHODS: FunctionEntries<2> = FunctionEntries::new([
7070
FunctionEntryBuilder::new(c_str_ptr!("__destruct"), Some(php_fn!(mini_curl_destruct)))
7171
.arg_info(&ARG_INFO_VOID)
7272
.build(),
73+
FunctionEntryBuilder::new(c_str_ptr!("exec"), Some(php_fn!(mini_curl_exec)))
74+
.arg_info(&ARG_INFO_VOID)
75+
.build(),
7376
]);
7477

7578
#[php_function]
@@ -85,13 +88,7 @@ pub fn mini_curl_construct(execute_data: &mut ExecuteData) -> impl SetVal {
8588

8689
if !url.is_empty() {
8790
if let Err(e) = easy.url(url) {
88-
unsafe {
89-
php_error_docref0(
90-
null(),
91-
E_WARNING as i32,
92-
format!("curl set failed: {}\0", e).as_ptr().cast(),
93-
);
94-
}
91+
error_doc_ref(Level::Warning, format!("curl set failed: {}\0", e));
9592
return ReturnValue::Bool(false);
9693
}
9794
}
@@ -101,6 +98,35 @@ pub fn mini_curl_construct(execute_data: &mut ExecuteData) -> impl SetVal {
10198
ReturnValue::Null
10299
}
103100

101+
#[php_function]
102+
pub fn mini_curl_exec(execute_data: &mut ExecuteData) -> impl SetVal {
103+
if execute_data.parse_parameters::<()>().is_none() {
104+
return ReturnValue::Bool(false);
105+
}
106+
107+
let mut data = Vec::new();
108+
109+
let this = execute_data.get_this();
110+
let ptr = MINI_CURL_CE.read_property(this, "_rust_easy_ptr");
111+
let value = ptr.try_into_value().unwrap();
112+
let ptr = value.into_long().unwrap();
113+
114+
let mut handle = unsafe { Box::from_raw(ptr as *mut Easy) };
115+
let mut transfer = handle.transfer();
116+
transfer
117+
.write_function(|new_data| {
118+
data.extend_from_slice(new_data);
119+
Ok(new_data.len())
120+
})
121+
.unwrap();
122+
transfer.perform().unwrap();
123+
drop(transfer);
124+
125+
Box::into_raw(handle);
126+
127+
ReturnValue::String(String::from_utf8(data).unwrap())
128+
}
129+
104130
#[php_function]
105131
pub fn mini_curl_destruct(execute_data: &mut ExecuteData) -> impl SetVal {
106132
if execute_data.parse_parameters::<()>().is_none() {

examples/mini-curl/tests/php/test.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
error_reporting(E_ALL);
66

77
$mc = new MiniCurl("http://httpbin.org/ip");
8-
var_dump($mc);
8+
$response = $mc->exec();
9+
var_dump($response);
910

1011
function assert_eq($left, $right) {
1112
if ($left !== $right) {

phper/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Version `0.1.x` will be a preview version.
3030
*/
3131

3232
mod error;
33+
pub mod main;
3334
mod utils;
3435
pub mod zend;
3536

phper/src/main/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod php;

phper/src/main/php.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
use crate::zend::errors::Level;
2+
use std::{os::raw::c_int, ptr::null};
3+
4+
pub fn error_doc_ref(level: Level, message: impl ToString) {
5+
let mut message = message.to_string();
6+
message.push('\0');
7+
8+
unsafe {
9+
#[cfg(phper_php_version = "7.4")]
10+
crate::sys::php_error_docref(null(), level as c_int, message.as_ptr().cast());
11+
12+
#[cfg(any(
13+
phper_php_version = "7.3",
14+
phper_php_version = "7.2",
15+
phper_php_version = "7.1",
16+
phper_php_version = "7.0",
17+
))]
18+
crate::sys::php_error_docref0(null(), level as c_int, message.as_ptr().cast());
19+
}
20+
}

phper/src/zend/errors.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
use crate::sys::{E_ERROR, E_NOTICE, E_WARNING};
2+
3+
#[repr(u32)]
4+
#[derive(Copy, Clone, PartialEq)]
5+
pub enum Level {
6+
Error = E_ERROR,
7+
Warning = E_WARNING,
8+
Notice = E_NOTICE,
9+
}

phper/src/zend/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
pub mod api;
22
pub mod compile;
3+
pub mod errors;
34
pub mod exceptions;
45
pub mod ini;
56
pub mod modules;

phper/src/zend/types.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,13 @@ impl<'a> Value<'a> {
703703
}
704704
}
705705
}
706+
707+
pub fn into_long(self) -> Option<i64> {
708+
match self {
709+
Self::Long(l) => Some(l),
710+
_ => None,
711+
}
712+
}
706713
}
707714

708715
pub enum ReturnValue<'a> {

0 commit comments

Comments
 (0)