Php::Value
phpcppPhp::Value 对象是一个 zval 变量的包装器,但它完全隐藏了 zval 处理的复杂。 我们通过Php::Value 对象来转换php 与cpp 的变量类型
- Php::Value 对象可用于存储标量变量, 因为C++ 的数据类型跟PHP 存在很大的区别,在不考虑性能的情况下,我们可以直接用Php::Value 声明php所有的标量类型
Php::Value value1 = 1234;
Php::Value value2 = "this is a string";
Php::Value value3 = std::string("another string");
Php::Value value4 = nullptr;
Php::Value value5 = 123.45;
Php::Value value6 = true;
- Php::value 同样也可以自动转化为cpp的数据类型
void myFunction(const Php::Value &value)
{
int value1 = value;
std::string value2 = value;
double value3 = value;
bool value4 = value;
}
- 字符串
在1中我们已经知道php的变量能用Php::Value 对象来接收,同时用Php::Value对象来返回(有返回值的函数,下面我们会具体讲到),但这对于实际处理字符串我们就需要用到cpp的char char* 以及string 对象了.我们先来理解下char char* std::string
- char []定义的是一个字符数组,注意强调是数组。eg.char buffer[6]=“hello”;char数组末尾以’\0’结束,在定义个char数组时一定要给结束符’\0’预留空间;
- char * 定义的是一个字符串指针,注意强调是指针;eg: char *p = buffer 定义了一个char型的指针,它只知道所指向的内存单元,并不知道这个内存单元有多大
- std::string 是C++标准库的一个重要的部分,主要用于字符串处理;里面实现了迭代器,包含size,length 等字符属性方法;
char buffer[6]="hello";
char *p = buffer;
std::string s = buffer;
Php::Value v = s;
分别用char char* string 来实现定长随机数
/**
*
* 通过 char * 指针获取定长随机字符
* */
Php::Value gen_by_charp(Php::Parameters ¶ms)
{
//长度参数
int len = params[0];
//声明返回值长度,并返回指针给str
char* str = new char[len+1];
//srand函数是随机数发生器rand的初始化函数,我们常常使用系统时间来初始化;
//使用time函数来获取系统时间,得到的值是一个时间戳,
srand(time(NULL)+1);
for (int i = 0; i < len; ++i)
{
switch ((rand() % 3))
{
case 1:
str[i] = 'A' + rand() % 26;
break;
case 2:
str[i] = 'a' + rand() % 26;
break;
default:
str[i] = '0' + rand() % 10;
break;
}
}
str[len+1] = '\0';
//str 本是Php::Value 对象
return str;
}
/**
*
* 通过 char 获取定长随机字符
* */
Php::Value gen_by_char(Php::Parameters ¶ms)
{
int len = params[0];
srand(time(NULL)+2);
char str[len+1];
int i;
for (i = 0; i < len; ++i)
{
switch ((rand() % 3))
{
case 1:
str[i] = 'A' + rand() % 26;
break;
case 2:
str[i] = 'a' + rand() % 26;
break;
default:
str[i] = '0' + rand() % 10;
break;
}
}
str[len+1] = '\0';
return str;
}
/**
*
* 通过 string 获取定长随机字符
* */
Php::Value gen_by_string(Php::Parameters ¶ms)
{
int len = params[0];
srand(time(NULL)+3);
std::string str = "";
for (int i = 0; i < len; ++i)
{
switch ((rand() % 3))
{
case 1:
str += 'A' + rand() % 26;
break;
case 2:
str += 'a' + rand() % 26;
break;
default:
str += '0' + rand() % 10;
break;
}
}
return str;
}
php test
$strLength =32;
echo "---\n\t";
echo gen_by_char($strLength);
echo "---\n\t";
echo gen_by_charp($strLength);
echo "---\n\t";
echo gen_by_string($strLength);
echo "---\n\t";
// ---
// 3XRi6j3K053cYPY3q6vl8490pB42n7mh---
// epSNJ67WtPUTV33qZhh30596n0pqetC8----
// ZNU17oMcStA7Q85pxkW0E4WNpN4xxYZz---
上面通过修改srand种子初始值大道三个随机字符不一致;
完整代码:https://github.com/tiway-deng/phpcpp-/tree/main/Tiway-var
- 数组
PHP 支持两种数组类型:常规数组(由数字索引)和关联数组(由字符串索引)。Php::Value 对象也支持数组,在cpp 读取和操作只要是通过Php::Value 对象来操作我们都不难理解,基本等同于php 的数组,可以在php::value 对象声明多维数组并对数组key 和value 都没有限制类型;
Php::Value assoc2;
assoc2[0] = "0";
assoc2["x"] = "info@example.com";
assoc2["y"] = nullptr;
assoc2["z"][0] = "a";
assoc2["z"][1] = "b";
assoc2["z"][2] = "c";
但是通常我们都需要对数组进行复杂的操作,这时候我们可能就用到map, vector
- vector
向量 相当于一个数组
在内存中分配一块连续的内存空间进行存储。支持不指定vector大小的存储。STL内部实现时,首先分配一个非常大的内存空间预备进行存储,即capacituy()函 数返回的大小, 当超过此分配的空间时再整体重新放分配一块内存存储,这给人以vector可以不指定vector即一个连续内存的大小的感觉。通常此默认的内存分配 能完成大部分情况下的存储。
优点: (1) 不指定一块内存大小的数组的连续存储,即可以像数组一样操作,但可以对此数组
进行动态操作。通常体现在push_back() pop_back()
(2) 随机访问方便,即支持[ ]操作符和vector.at()
(3) 节省空间。
缺点: (1) 在内部进行插入删除操作效率低。
(2) 只能在vector的最后进行push和pop,不能在vector的头进行 push和pop。
(3) 当动态添加的数据超过vector默认分配的大小时要进行整体的重新分配、拷贝与释放。 - map
map映照容器的元素数据是一个键值和一个映照数据组成的,键值与映照数据之间具有一一映照的关系。
map映照容器的数据结构是采用红黑树来实现的,插入键值的元素不允许重复,比较函数只对元素的键值进行比较,元素的各项数据可通过键值检索出来。
使用map容器需要头文件包含语句“#include
Php::Value array;
array[0] = "apple";
array[1] = "banana";
array[2] = "tomato";
std::vector<std::string> fruit = array;
fruit .size() //获取向量中元素个数
fruit .empty() //判断向量是否为空
fruit .clear() //清空向量中的元素
// 容器迭代
vector<int>::iterator it;
for(it=fruit.begin();it!=fruit.end();it++)
{
}
//map
std::map<int,std::string> map = array;
map<string,float> :: iterator it ;
for(it = m.begin() ; it != m.end() ; it ++)
{
cout << (*it).first << " : " << (*it).second << endl ;
}
以上是通过cpp的数据类型才操作数组,其实Php::Value类实现begin()和end()方法就像许多C ++ STL容器所以Php::Value 本身也能实现迭代;
/**
* Function that accepts an array as parameter
* @param array
*/
void myFunction(const Php::Value &value)
{
// assum the value variable holds an array or object, it then
// is possible to iterate over the values or properties
for (auto &iter : value)
{
// output key and value
Php::out << iter.first << ": " << iter.second << std::endl;
}
}
以上大部分例子来源官网:参考变量运用
总结
- 想要用数量的运用php-cpp,除了要掌握Php::Value 类以为,还需要掌握cpp数据类型
- 需要了解常用的STL(Standard Template Library),即标准模板库
- 以上官网还有对于对象这种类型的操作,我们放在写cpp类的时候一起了解
- 要区别理解php 数组与 cpp 的vector, map ,list 存储形式及操作