Skip to content

Commit 2639353

Browse files
committed
feat(array): support Vec<(K,V)> for hashtables
Refs: #425
1 parent 1166e29 commit 2639353

File tree

4 files changed

+397
-7
lines changed

4 files changed

+397
-7
lines changed

guide/src/types/hashmap.md

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,17 @@ numeric key, the key is represented as a string before being inserted.
1414
Converting from a `HashMap` to a zval is valid when the key implements
1515
`AsRef<str>`, and the value implements `IntoZval`.
1616

17+
<div class="warning">
18+
19+
When using `HashMap` the order of the elements it not preserved.
20+
21+
HashMaps are unordered collections, so the order of elements may not be the same
22+
when converting from PHP to Rust and back.
23+
24+
If you need to preserve the order of elements, consider using `Vec<(K, V)>` or
25+
`Vec<ArrayKey, V)>` instead.
26+
</div>
27+
1728
## Rust example
1829

1930
```rust,no_run
@@ -49,9 +60,92 @@ var_dump(test_hashmap([
4960
Output:
5061

5162
```text
52-
k: hello v: world
5363
k: rust v: php
64+
k: hello v: world
5465
k: 0 v: okk
66+
array(3) {
67+
[0] => string(3) "php",
68+
[1] => string(5) "world",
69+
[2] => string(3) "okk"
70+
}
71+
```
72+
73+
## `Vec<(K, V)>` and `Vec<ArrayKey, V>`
74+
75+
`Vec<(K, V)>` and `Vec<ArrayKey, V>` are used to represent associative arrays in PHP
76+
where the keys can be strings or integers.
77+
78+
If using `String` or `&str` as the key type, only string keys will be accepted.
79+
80+
For `i64` keys, string keys that can be parsed as integers will be accepted, and
81+
converted to `i64`.
82+
83+
If you need to accept both string and integer keys, use `ArrayKey` as the key type.
84+
85+
### Rust example
86+
87+
```rust,no_run
88+
# #![cfg_attr(windows, feature(abi_vectorcall))]
89+
# extern crate ext_php_rs;
90+
# use ext_php_rs::prelude::*;
91+
#[php_function]
92+
pub fn test_vec_kv(vec: Vec<(String, String)>) -> Vec<String, String> {
93+
for (k, v) in vec.iter() {
94+
println!("k: {} v: {}", k, v);
95+
}
96+
97+
vec.into_iter()
98+
.map(|(_, v)| v)
99+
.collect::<Vec<_>>()
100+
}
101+
102+
#[php_function]
103+
pub fn test_vec_arraykey(vec: Vec<(ArrayKey, String)>) -> Vec<String> {
104+
for (k, v) in vec.iter() {
105+
println!("k: {} v: {}", k, v);
106+
}
107+
108+
vec.into_iter()
109+
.map(|(_, v)| v)
110+
.collect::<Vec<_>>()
111+
}
112+
# fn main() {}
113+
```
114+
115+
## PHP example
116+
117+
```php
118+
<?php
119+
120+
declare(strict_types=1);
121+
122+
var_dump(test_vec_kv([
123+
['hello', 'world'],
124+
['rust', 'php'],
125+
['okk', 'okk'],
126+
]));
127+
128+
var_dump(test_vec_arraykey([
129+
['hello', 'world'],
130+
[1, 'php'],
131+
["2", 'okk'],
132+
]));
133+
```
134+
135+
Output:
136+
137+
```text
138+
k: hello v: world
139+
k: rust v: php
140+
k: okk v: okk
141+
array(3) {
142+
[0] => string(5) "world",
143+
[1] => string(3) "php",
144+
[2] => string(3) "okk"
145+
}
146+
k: hello v: world
147+
k: 1 v: php
148+
k: 2 v: okk
55149
array(3) {
56150
[0] => string(5) "world",
57151
[1] => string(3) "php",

0 commit comments

Comments
 (0)