hiphop 1.0 开发问题总结 原创-胡志广
???Access {
?????* {
???????File =/export/hphp_project/xxx.xxx.com_hphp_update_20120803/access.log
???????Format = %h %l %u %t "%r" %>s %b
?????}
?
}
?
File这里配置的都是绝对路径即可
?
4.??Hiphop?添加静态扩展首先进入src/idl目录创建一个[extension name].idl.php文件
如:
hello.idl.php
:> hello.idl.php
在src/idl目录中创建
然后再执行schema.php?,生成idl模板,如:
/export/server/php/bin/php schema.php hello>hello.idl.php
生成好后,我们编写idl文件模板,可以参照里面的内容写方法和类,如:
DefineFunction(
?array(
???'name'?? =>"hello_world",
???'desc'?? => "helloworld",
??? 'return' => array(
?????'type'?? => Int64,
?????'desc'?? => "11,out helloworld!",
???),
? ));
编辑好hello.idl.php后,我们先备份一下
Src/system/ext.inc和src/runtime/ext/ext.h这2个文件,因为在下面执行make后,这2个文件会被清空;
然后我们返回到src目录下,执行:
EXT=[existingextension name] make -C idl update命令,如:
EXT=hello make-C idl update
然后会生成ext_hello.cpp ext_hello.h hello.inc?在idl目录
在src/runtime/ext/profile/目录下生成extprofile_hello.h
在src/system目录下生成hello.inc文件
然后我们把ext_hello.cpp ext_hello.h这2个文件拷贝到src/runtime/ext目录下,然后我们为ext_hello.cpp里面添加实现,如我们修改ext_hello.cpp内容:
int64f_hello_world() {
?
??? printf("hello world");
??? return 11;
}
然后保存,编译好后,该方法会返回11?,可进行测试。
然后我们把刚才备份的src/system/ext.inc和src/runtime/ext/ext.h拷贝回来覆盖现有的这2个文件,然后我们编辑src/system/ext.inc文件,在下面增加上一行:
#include "hello.inc"
我们需要增加扩展的inc文件,保存;
然后我们再修改src/runtime/ext/ext.h文件,添加上一行:
#include<runtime/ext/profile/extprofile_hello.h>
添加上我们扩展的extprofile的头文件
修改完这2个文件后,我们返回到主目录,创建一个build1目录,进入到build1目录中执行?cmake ../
然后cmake?完毕后执行make?安装完hiphop后我们在编译php文件会发现我们新加扩展的方法可以用了
?
?
5.??Mongodb c++ client安装下载mongodb-linux-x86_64-2.2.0-client.tgz,然后解压后后执行:
Scons
Scons需要预先安装
执行完scons后,打开build,下面有一个libmongoclient.a文件,这个文件cp?到$CMAKE_PREFIX_PATH的lib下
然后
cp -rmongo-cxx-driver-v2.2/src/mongo $CMAKE_PREFIX_PATH
?
如果执行g++编译:
g++ test_mongodb.cpp -I/export/dev/usr/include/ /export/dev/usr/lib/libmongoclient.a/usr/lib64/libboost_thread-mt.so /usr/lib64/libboost_filesystem.so/usr/lib64/libboost_program_options.so -o test_mongodb
?
?
?
6.??hiphop?类实现CMakeFiles/program.dir/cpp/001.cpp.o: Infunction `HPHP::pm_php$test_php(bool, HPHP::LVariableTable*,HPHP::Globals*)':\n001.cpp:(.text+0xbf): undefined reference to`HPHP::coo_Mongo()'\n001.cpp:(.text+0xc7): undefined reference to`HPHP::c_Mongo::create()'\ncollect2: ld \xb7\xb5\xbb\xd8 1\nmake[2]: ***[program] \xb4\xed\xce\xf3 1\nmake[1]: *** [CMakeFiles/program.dir/all]\xb4\xed\xce\xf3 2\nmake: *** [all] \xb4\xed\xce\xf3 2\n
compiling and linking CPP files took0'50" (50022 ms) wall time
?
当编译php时报了如上错误,说明没有coo_Mongo和c_Mongo::create()?的实现
?
这2个是在src/system/gen/sys目录下的dynamic_table_class.cpp中实现的,然后在dynamic_table_class.cpp中还有一些类的函数等注册信息,具体内容如下:
?
//这里是注册扩展类声明的位置coo_[扩展类名],如Mongo
ObjectData *coo_Mongo() {
?return NEWOBJ(c_Mongo)();
}
//实现类注册
IMPLEMENT_CLASS(Mongo)
//接口表数组,必须
//第一参数是hash
//第二个参数是flag 0,1
//第三个参数是名字
//第四个参数是回调函数
//参照InstanceOfInfo?结构
extern const InstanceOfInfocw_Mongo$$instanceof_table[] = {
?{0x414077AFA9BA239FLL,1,"Mongo",&cw_Mongo},
};
//这个也是必要的,内容所有的都一致,只是名字为扩展名称,如cw_[扩展名称]
const int cw_Mongo$$instanceof_index[] = {
? 1,
?-1,0,
};
//调用信息
//第一参数调用方法
//第二个参数是调用最少参数
//第三个参数是调用参数总数
//第四个参数引用flags(不太清楚)
//参数参照CallInfo结构
//名字构成ci_扩展类名$$方法名称,如ci_Mongo$$__destruct,方法名称从生成的ext_扩展.h中的如果是普通方法把名字直接粘贴过来ci_Mongo$$函数名,如果是
extern const CallInfo ci_Mongo$$__destruct= { (void*)&c_Mongo::i___destruct, (void*)&c_Mongo::ifa___destruct, 0,4, 0x0000000000000000LL};
extern const CallInfo ci_Mongo$$__construct= { (void*)&c_Mongo::i___construct, (void*)&c_Mongo::ifa___construct,2, 4, 0x0000000000000000LL};
extern const CallInfo ci_Mongo$$___get = {(void*)&c_Mongo::i___get, (void*)&c_Mongo::ifa___get, 1, 4,0x0000000000000000LL};
?
//这里也是声明函数信息,所有内容几乎一致
//方法定义
Variant c_扩展类名称::i___函数名称(MethodCallPackage&mcp, CArrRef params) {
?return invoke_meth_few_handler(mcp, params, &ifa___函数名称);
}
Variant c_Mongo::i___construct(MethodCallPackage&mcp, CArrRef params) {
?return invoke_meth_few_handler(mcp, params, &ifa___construct);
}
Variantc_Mongo::i___destruct(MethodCallPackage &mcp, CArrRef params) {
?return invoke_meth_few_handler(mcp, params, &ifa___destruct);
}
Variant c_Mongo::i___get(MethodCallPackage&mcp, CArrRef params) {
?return invoke_meth_few_handler(mcp, params, &ifa___get);
}
?
Variantc_Mongo::ifa___construct(MethodCallPackage &mcp, int count,INVOKE_FEW_ARGS_IMPL_ARGS) {
? if(UNLIKELY(mcp.obj == 0)) {
???return ObjectData::ifa_dummy(mcp, count, INVOKE_FEW_ARGS_PASS_ARGS,ifa___construct, coo_Mongo);
? }
?c_Mongo *self ATTRIBUTE_UNUSED (static_cast<c_Mongo*>(mcp.obj));
?//if (UNLIKELY(count<1 || count > 2)) return throw_toomany_arguments("__construct",1,2, 1);
?CVarRef arg0(a0);
?//if (count <= 1) return (self->t___construct(arg0));
?CVarRef arg1(a1);
?return (self->t___construct(arg0,arg1),null);
}
Variantc_Mongo::ifa___destruct(MethodCallPackage &mcp, int count, INVOKE_FEW_ARGS_IMPL_ARGS){
? if(UNLIKELY(mcp.obj == 0)) {
???return ObjectData::ifa_dummy(mcp, count, INVOKE_FEW_ARGS_PASS_ARGS,ifa___destruct, coo_Mongo);
? }
?c_Mongo *self ATTRIBUTE_UNUSED (static_cast<c_Mongo*>(mcp.obj));
? if(UNLIKELY(count > 0)) return throw_toomany_arguments("__destruct",0, 1);
?return (self->t___destruct());
}
?
Variantc_Mongo::ifa___get(MethodCallPackage &mcp, int count,INVOKE_FEW_ARGS_IMPL_ARGS) {
? if(UNLIKELY(mcp.obj == 0)) {
???return ObjectData::ifa_dummy(mcp, count, INVOKE_FEW_ARGS_PASS_ARGS,ifa___get, coo_Mongo);
? }
?c_Mongo *self ATTRIBUTE_UNUSED (static_cast<c_Mongo*>(mcp.obj));
?//if (UNLIKELY(count != 1 )) returnthrow_toomany_arguments("___get", 1,1, 1);
?CVarRef arg0(a0);
?return (self->t___get(arg0));
}
?
extern const MethodCallInfoTablecw_Mongo$$call_info_table[] = {};
?// {0x0D31D0AC229C615FLL, 0, 11, "__construct",&ci_Mongo$$__construct },
?// {0x7F974836AACC1EF3LL, 1, 10, "__destruct", &ci_Mongo$$__destruct},
//};
//extern const intcw_Mongo$$call_info_index[] = {
//?3,
//?-1,-1,-1,0,
//};
?
extern const intcw_Mongo$$call_info_index[] = {
? };
?
?
c_Mongo *c_Mongo::create(String a0,Varianta1) {
?CountableHelper h(this);
?init();
?t___construct(a0,a1);
?clearNoDestruct();
?return this;
}
extern const MethodCallInfoTablecw_Mongo$$call_info_table[];
extern const intcw_Mongo$$call_info_index[];
extern const InstanceOfInfocw_Mongo$$instanceof_table[];
extern const intcw_Mongo$$instanceof_index[];
const ObjectStaticCallbacks cw_Mongo = {
?(ObjectData*(*)(ObjectData*))coo_Mongo,
?cw_Mongo$$call_info_table,cw_Mongo$$call_info_index,
?cw_Mongo$$instanceof_table,cw_Mongo$$instanceof_index,
?&c_Mongo::s_class_name,
?0,&ci_Mongo$$__construct,0,0,0x0,
?&c_Mongo::s_cls
};
?
?
7.??Hiphop编译错误:make[5]: *** write jobserver: Bad filedescriptor.? Stop.\nmake[5]: *** Waitingfor unfinished jobs....\nmake[5]: *** write jobserver: Bad filedescriptor.? Stop.\nmake[4]: *** [CMakeFiles/program.dir/all]Error 2\nmake[3]: *** [all] Error 2\n
hphp failed
?
在扩展中添加mongo的连接在类函数中就会出现上面的问题,但是第二次编译后就没问题了
DBClientConnection c;
?
?
8.??Hiphop编译错误/export/dev/hiphop-php/src/system/gen/sys/dynamic_table_class.cpp:1309:error: prototype for 'HPHP::c_MongoCursor* HPHP::c_MongoCursor::create(HPHP::Variant,HPHP::String, HPHP::Array, HPHP::Array)' does not match any in class'HPHP::c_MongoCursor'
/export/dev/hiphop-php/src/runtime/ext/ext_mongo.h:55:error: candidate is: HPHP::c_MongoCursor*HPHP::c_MongoCursor::create(HPHP::Object, HPHP::String, HPHP::Array,HPHP::Array)
make[2]: ***[src/CMakeFiles/hphp_runtime_static.dir/system/gen/sys/dynamic_table_class.cpp.o]Error 1
make[1]: ***[src/CMakeFiles/hphp_runtime_static.dir/all] Error 2
make: *** [all] Error 2
当报这个错误时,是由于我们的dynamic_table_class.cpp文件的1309行的
c_MongoCursor::create…的类型错误了,所以参照
HPHP::c_MongoCursor*HPHP::c_MongoCursor::create(HPHP::Object, HPHP::String, HPHP::Array,HPHP::Array)提示把类型改过来就可以了
?
9.??Hiphop编译错误../../../bin/libhphp_runtime.a(dynamic_table_class.cpp.o):(.rodata+0x1360):undefined reference to`HPHP::c_MongoCursor::i_rewind(HPHP::MethodCallPackage&, HPHP::Arrayconst&)'
collect2: ld returned 1 exit status
make[2]: *** [src/hphp/hphp] Error 1
make[1]: ***[src/hphp/CMakeFiles/hphp.dir/all] Error 2
make[1]: *** Waiting for unfinishedjobs....
../../../bin/libhphp_runtime.a(dynamic_table_class.cpp.o):(.rodata+0x1360):undefined reference to`HPHP::c_MongoCursor::i_rewind(HPHP::MethodCallPackage&, HPHP::Arrayconst&)'
collect2: ld returned 1 exit status
当报这个错误时,提示没有引用i_rewind,说明我们未对i_rewind进行定义
我们只需要添加:
Variantc_MongoCursor::i_rewind(MethodCallPackage &mcp, CArrRef params) {
?return invoke_meth_few_handler(mcp, params,&ifa_rewind);
?}
声明一下,就可以了
?
10.????????Hiphop编译错误HipHop Warning:? Missing argument 1 for key() in test1.php online 6
当报这个错误时,是因为调用key()函数的方式出现了问题,如:
$a=new Mongo();
$a.key();
这样就会报上面的错误,因为php调用函数是用->
所以把$a.key()改为$a->key()就没有问题了
?
11.????????Hiphop创建对象指针c_VectorIterator* it =NEWOBJ(c_VectorIterator)();
it->test();
?
?
12.????????hiphop编译错误当编译php使用hiphop时,报了如下错误:
Core dumped: Segmentation fault
这可能是由于类调用方法不存在引发的段错误,如:
$a=new Mongo();
$a->key();
但是Mongo中没有key,那么就会出现上面的错误,段错误发生很多,这只是其中一种情况
?
13.????????Hiphop编译错误error: 'c_Closure' was not declared in thisscope
当编译hiphop时,报了如上错误,是由于没有把c_Closure类的头文件引入进来,引入后就没问题了
?
14.????????Hiphop?的call_info_table和call_info_index当使用hiphop?编译php时报出如下错误:
HipHop Fatal error: Unknown methodMongoCursor::rewind in test1.php on line 2
?
这里提示找不到方法rewind,是由于在dynamic_table_class.cpp这个类中定义MongoCursor的rewind中没有对call_info_table和call_info_index进行定义,这2个表都需要定义,否则会找不到函数;
call_info_index这个矩阵是有一定的规律的和call_info_table的数量是有关系的,和名字无关,所以当call_info_table数量相同时,所产生的call_info_index是一样的,现在找不到好的方法生成dynamic_table_class.cpp,所以可以借助一个php,在php中实现好类和函数,然后通过hiphop编译,然后在hiphop编译好的文件中找到cpp目录下的001.cpp(这里一个文件是由于在编译时定义cluster-count=1),然后找到相应的call_info_table和call_info_index拷贝到dynamic_table_class.cpp文件即可。
?
如:
extern const MethodCallInfoTablecw_myIterator___call_info_table[] = {
? {0x7F974836AACC1EF3LL, 1, 10, "__destruct",&ci_myIterator_____destruct },
? {0x6413CB5154808C44LL, 1, 5, "valid", &ci_myIterator___valid },
? {0x337E695DE87C57C7LL, 1, 8, "key", &ci_myIterator___key },
? {0x3C6D50F3BB8102B8LL, 1, 4, "next", &ci_myIterator___next },
? {0x1670096FDE27AF6ALL, 1, 6, "rewind", &ci_myIterator___rewind },
? {0x5B3A4A72846B21DCLL, 1, 7, "current", &ci_myIterator___current},
? {0x0D31D0AC229C615FLL, 1, 11, "__construct",&ci_myIterator_____construct },
};
?
//这个和call_info_table的数量是有关系的
extern const intcw_myIterator___call_info_index[] = {
? 15,
?-1,-1,-1,0,1,-1,-1,2,
?3,-1,4,-1,5,-1,-1,6,
?
};
?
所以call_info_table和call_info_index是必要的
?
?
15.????????Hiphop支持Iteratorextern const InstanceOfInfocw_MongoCursor$$instanceof_table[] = {
?{0x414077AFA9BA239FLL,1,"MongoCursor",&cw_MongoCursor},
{0x66679538C5E6F0A1LL,1,"Traversable",(constObjectStaticCallbacks*)2},
?{0x0636A5F84AF9D29ELL,1,"Iterator",(constObjectStaticCallbacks*)2}
? };
?
如果想让类支持Iterator,那么就在dynamic_table_class.cpp类中找到instanceof_table,然后加上{0x0636A5F84AF9D29ELL,1,"Iterator",(constObjectStaticCallbacks*)2}这句话就可以了
?
?
16.????????Hiphop类返回类,调用方法如果在hiphop中需要返回一个类,并且调用它的方法,那么被返回类的方法一定要在call_info_table和call_info_index这2个数据中出现否则会报:
HipHop Fatal error: Unknown methodMongoCursor::rewind in test1.php on line 2
call_info_table和call_info_index是在dynamic_table_class.cpp类中添加
?
17.????????hiphop编译好的php目录结构这个是编译好hiphop的目录结构
cls ?CMakeCache.txt?CMakeFiles?cmake_install.cmake?CMakeLists.txt? cpp? Makefile?php? program? sep_extensions.mk? sys
?
?
cls中是当前编译的类的头文件
cpp是编译好的实现内容
?
18.????????hiphop编译错误/export/hphp_project/test/php/test.cpp: Infunction 'HPHP::Variant HPHP::pm_php$test_php(bool, HPHP::LVariableTable*,HPHP::Globals*)':\n/export/hphp_project/test/php/test.cpp:21: error: 'classHPHP::GlobalVariables' has no member named'run_pm_php$test_php'\n/export/hphp_project/test/php/test.cpp:25: error: 'classHPHP::GlobalVariables' has no member named 'gvm_obj'\nmake[2]: ***[CMakeFiles/program.dir/php/test.cpp.o] Error 1\nmake[1]: ***[CMakeFiles/program.dir/all] Error 2\nmake: *** [all] Error 2\n
?
当报如上错误时,一般是编译文件出现冲突了,所以清理一遍编译目录,重新编译即可
?
?
19.????????Hiphop实现Iterator在ext_mongo.h中:
#include <runtime/base/base_includes.h>
?
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
?
?
///////////////////////////////////////////////////////////////////////////////
// class MongoCursor
?
FORWARD_DECLARE_CLASS_BUILTIN(MongoCursor);
class c_MongoCursor : public ExtObjectData{
?public:
?DECLARE_CLASS(MongoCursor, MongoCursor, ObjectData)
?
? //这个是Iterator的游标
?int64 m_position;
? //这个是保存内容的集合
?Array m_array;
?
? //need to implement
?public: c_MongoCursor(const ObjectStaticCallbacks *cb =&cw_MongoCursor);
?public: ~c_MongoCursor();
?public: void t___construct(CObjRef connection, CStrRef ns, CArrRef query= null_array, CArrRef fields = null_array);
?DECLARE_METHOD_INVOKE_HELPERS(__construct);
?public: Variant t_current();
?DECLARE_METHOD_INVOKE_HELPERS(current);
?public: int64 t_key();
?DECLARE_METHOD_INVOKE_HELPERS(key);
?public: void t_next();
?DECLARE_METHOD_INVOKE_HELPERS(next);
?public: void t_rewind();
?DECLARE_METHOD_INVOKE_HELPERS(rewind);
?public: bool t_valid();
?DECLARE_METHOD_INVOKE_HELPERS(valid);
?public: Variant t___destruct();
?DECLARE_METHOD_INVOKE_HELPERS(__destruct);
?
? //implemented by HPHP
?public: c_MongoCursor *create(Object connection, String ns, Array query= null_array, Array fields = null_array);
?
};
}
?
在ext_mongo.cpp中:
#include <runtime/ext/ext_mongo.h>
#include<runtime/ext/ext_continuation.h>
#include <iostream>
?
using namespace std;
?
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
c_MongoCursor:: c_MongoCursor(constObjectStaticCallbacks *cb):ExtObjectData(cb){
???????? cout<<"start"<<endl;?????
???????? //在构造函数中初始化游标
???????? m_position= 0LL;
???m_array.append(new Variant("1"));
???m_array.append(new Variant("2"));
???m_array.append(new Variant("3"));
?
}
?c_MongoCursor:: ~c_MongoCursor(){
???????? cout<<"end"<<endl;
}
?void c_MongoCursor::t___construct(CObjRef connection, CStrRef ns,CArrRef query, CArrRef fields){
???????? //在(php)构造函数中初始化游标
???????? m_position= 0LL;
???//m_array.append(new Variant("1"));
???//m_array.append(new Variant("2"));
???//m_array.append(new Variant("3"));
???????? cout<<"construct"<<endl;
???????? }
Variant?c_MongoCursor::t_current(){
???????? cout<<"current"<<endl;
???????? //m_array.rvalAt(m_position, AccessFlags::Error);返回当前位置的array
???????? returnm_array.rvalAt(m_position, AccessFlags::Error);
}
int64?c_MongoCursor::t_key(){
???????? cout<<"key"<<endl;
???????? //返回当前位置
???????? returnm_position;
}
void?c_MongoCursor::t_next(){
???????? cout<<"next"<<endl;
???????? //对游标进行累加
???????? ++m_position;
}
//初始化
void?c_MongoCursor::t_rewind(){
???INSTANCE_METHOD_INJECTION_BUILTIN(MongoCursor,MongoCursor::rewind);
???m_position = 0LL;
???????? cout<<"rewind"<<endl;??
}
//判断是否是最后一个对象
bool?c_MongoCursor:: t_valid(){
???????? cout<<"valid"<<endl;
???????? returnisset(m_array, m_position);
}
?Variant?c_MongoCursor::t___destruct(){
?????????????????? cout<<"destruct"<<endl;
???????? returnnull;
}
}
?
定义idl:
DefineFunction(
?array(
???'name'?? => 'current',
???'return' => array(
?????'type'?? => Variant,
???),
? ));
?
DefineFunction(
?array(
???'name'?? => 'key',
???'return' => array(
?????'type'?? => Int64,
???),
? ));
?
DefineFunction(
?array(
???'name'?? => 'next',
???'return' => array(
?????'type'?? => null,
???),
? ));
?
DefineFunction(
?array(
???'name'?? => 'rewind',
??? 'return' => array(
?????'type'?? => null,
???),
? ));
?
DefineFunction(
?array(
???'name'?? => 'valid',
???'return' => array(
?????'type'?? => Boolean,
???),
? ));
?
20.????????Hiphop编译失败../../../bin/libhphp_runtime.a(ext_mongo.cpp.o):In function `HPHP::c_Mongo::c_Mongo(HPHP::ObjectStaticCallbacks const*)':
ext_mongo.cpp:(.text+0x2f): undefinedreference to `vtable for HPHP::c_Mongo'
../../../bin/libhphp_runtime.a(ext_mongo.cpp.o):In function `HPHP::c_MongoDB::c_MongoDB(HPHP::ObjectStaticCallbacks const*)':
ext_mongo.cpp:(.text+0xbf): undefinedreference to `vtable for HPHP::c_MongoDB'
collect2: ld returned 1 exit status
make[2]: *** [src/hphp/hphp] Error 1
make[1]: ***[src/hphp/CMakeFiles/hphp.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
?
21.????????hiphop编译php失败CMakeFiles/program.dir/php/test1.cpp.o: Infunction `HPHP::pm_php$test1_php(bool, HPHP::LVariableTable*,HPHP::Globals*)':\ntest1.cpp:(.text+0x0): multiple definition of`HPHP::pm_php$test1_php(bool, HPHP::LVariableTable*, HPHP::Globals*)'\nCMakeFiles/program.dir/cpp/001.cpp.o:001.cpp:(.text+0x0):first defined here\ncollect2: ld \xb7\xb5\xbb\xd8 1\nmake[2]: *** [program]\xb4\xed\xce\xf3 1\nmake[1]: *** [CMakeFiles/program.dir/all] \xb4\xed\xce\xf32\nmake: *** [all] \xb4\xed\xce\xf3 2\n
compiling and linking CPP files took1'05" (65239 ms) wall time
?
如果报这个错误,那么把输出编译内容清空一下重新编译即可
?
?
22.????????Hiphop编译错误HipHop Fatal error: syntax error,unexpected T_OBJECT_OPERATOR in test_mongo.php on line 4
这个是因为php中定义的对象没有$
如:
test=new Mongo();
正确的应该是:
$test=new Mongo();
?
23.????????通过php用函数模板生成dynamic_table_class.cpp内容首先在php中定义好类和方法
然后通过HPHP_HOME/build/src/hphp/hphp?编译该php,编译好后,去编译后的目录的cpp文件夹下找到001.cpp(注意我们这里只编译一个php,cluster-count=1,这样主要为了方便查询)
然后我们打开001.cpp
从这里开始:
//cw_扩展名称___instanceof
extern const InstanceOfInfocw_Mongo___instanceof_table[] = {
?{0x656B62D3A5CF04D9LL,1,"Mongo",&cw_Mongo},
?};
…………………
中间内容省略
const ObjectStaticCallbacks cw_Mongo = {
?(ObjectData*(*)(ObjectData*))coo_Mongo,
?cw_Mongo___call_info_table,cw_Mongo___call_info_index,
?cw_Mongo___instanceof_table,cw_Mongo___instanceof_index,
?&c_Mongo::s_class_name,
?0,&ci_Mongo_____construct,0,0,0x0,
?&c_Mongo::s_cls
?};
到这里结束拷贝到dynamic_table_class.cpp这个文件中,然后在上面加上:
ObjectData *coo_Mongo () {
?return NEWOBJ(c_Mongo)();
}
IMPLEMENT_CLASS(Mongo)
这些内容即可,这2块拼接好后就是我们需要的class内容了,这里的mongo是扩展的名称,根据定义不同,可进行更改。
注:
dynamic_table_class.cpp通过hphp生成的变量名称ci和cw打头的和原生的有些区别,但是不影响,原生的dynamic_table_class.cpp生成的?ci和cw连接是用$$,hphp生成的是用____
如:
这个是hphp?生成的:
extern constInstanceOfInfo cw_Mongo___instanceof_table[] = {
?{0x656B62D3A5CF04D9LL,1,"Mongo",&cw_Mongo},
?};
这个是原生的:
extern const InstanceOfInfo cw_Mongo$$instanceof_table[] = {
?{0x656B62D3A5CF04D9LL,1,"Mongo",&cw_Mongo},
?};
?
24.????????Array?的头文件是Type_array.h(2)修改$HPHP_HOME/src/runtime/base/string_util.cpp
将String StringUtil::HtmlEncode(CStrRefinput, QuoteStyle quoteStyle,
????????????????????????????? const char*charset, bool nbsp)函数中的333行的:
if(strcasecmp(charset, "ISO-8859-1") == 0) {
?? ???utf8 = false;
?? } else if (strcasecmp(charset,"UTF-8")) {
?? ???throw NotImplementedException(charset);
?? }??????
中的throwNotImplementedException(charset);注释掉,就不会抛HipHopFatal error: GB2312 is not implemented yet异常了。
31.????????hiphop编译php失败CMakeFiles/program.dir/sys/literal_strings_0.no.cpp.o:In function `HPHP::init_literal_varstrings()':\nliteral_strings_0.no.cpp:(.text+0x0):multiple definition of`HPHP::init_literal_varstrings()'\nCMakeFiles/program.dir/sys/literal_strings_1.no.cpp.o:literal_strings_1.no.cpp:(.text+0x0):first defined here\ncollect2: ld \xb7\xb5\xbb\xd8 1\nmake[2]: *** [program]\xb4\xed\xce\xf3 1\nmake[1]: *** [CMakeFiles/program.dir/all] \xb4\xed\xce\xf32\nmake: *** [all] \xb4\xed\xce\xf3 2\n
compiling and linking CPP files took0'58" (58735 ms) wall time
hphp failed
当hiphop编译php失败报如上错误时,是由于编译的指定目录出现了冲突,所以把编译的指定目录清空后,重新编译就没有问题了。
编译路径如:
/export/dev/hiphop-php/build/src/hphp/hphptest_redis.php -k 1 --log=3 --cluster-count=1 -o /export/hphp_project/test
?
是–o?后面的路径
?
32.????????新版本的dynamic_table_class.cpp的hash值变小了如果更新版本后,注意每次添加新扩展时,需要对HASH值进行重新编译,因为旧的值在新版本中可能造成越界的警告:
如:
/export/dev/hiphop-php/src/system/gen/sys/dynamic_table_class.cpp:171:warning: overflow in implicit constant conversion
这里提示的是171行越界了,因为新版本的hash值变短了,所以之前旧的长所以造成了越界,
?
这是旧的hash值
extern const InstanceOfInfocw_MongoDB___instanceof_table[] = {
?{0x5999BDEDF7C49E1FLL,1,"MongoDB",&cw_MongoDB},
};
这是新的hash值:
extern const InstanceOfInfocw_Mongo___instanceof_table[] = {
?{0x5BD7C876,1,"Mongo",&cw_Mongo},
};
旧的(0x5999BDEDF7C49E1FLL)要比新的(0x5BD7C876)长,所以这里我们重新生成一遍,把就的hash值改了即可
需要改的变量为instanceof_table和call_info_table两个,改后就不会出现如上警告了
?
?
33.????????Hiphop类重复定义冲突错误make[2]: *** No rule to make target`cls/Fake$0.h', needed by `CMakeFiles/program.dir/cpp/001.cpp.o'.? Stop.\nmake[1]: ***[CMakeFiles/program.dir/all] Error 2\nmake: *** [all] Error 2\n
如果报了如Fake$0.h这样的错误,是由于在PHP文件中重复定义了类造成的,将一个删除即可。
?
?
34.????????Hiphop? debugcmake -DCMAKE_BUILD_TYPE=Debug .
make
?
?
35.????????编译的php不存在hphp:/export/dev/hiphop-php/src/util/job_queue.h:321:HPHP::JobQueueDispatcher<TJob, TWorker>::JobQueueDispatcher(int, bool,int, int, bool, void*, bool) [with TJob = OutputJob*, TWorker = OutputWorker]:Assertion `threadCount >= 1' failed
当执行
/export/dev/hiphop-php/build/src/hphp/hphpRedis1.php -k 1 --log=3 --cluster-count=1 -o /export/hphp_project/test
语句时报了如上错误,是由于Redis1.php不存在,改为正确的php路径的名字即可
?
?
36.????????Hiphop c++可以使用析构函数在hiphop的类中继承Sweepable类就可以使用析构函数了,如:
在ext_redis.h中添加上Sweepable继承,
class c_Redis : public ExtObjectData,publicSweepable {
?public:
……………………………………..
?
继承Sweepable了他后,就可以用~c_redis这个函数了
?
?
37.????????Php?的rawurlencode~不转换为%7E,hiphop的rawurlencode将~转换为%7E解决方法在src/runtime/base/zend/zend_url.cpp中的这个方法url_raw_encode是进行编码的
char *url_raw_encode(const char *s, int&len) {
?register int x, y;
?unsigned char *str;
?
? str= (unsigned char *)malloc(3 * len + 1);
? for(x = 0, y = 0; len--; x++, y++) {
???str[y] = (unsigned char) s[x];
???if ((str[y] < '0' && str[y] != '-' && str[y] != '.')||
?????(str[y] < 'A' && str[y] > '9') ||
???????(str[y] > 'Z' && str[y] < 'a' && str[y] != '_') ||
?????(str[y] > 'z')) {
?????str[y++] = '%';
?????str[y++] = hexchars[(unsigned char) s[x] >> 4];
?????str[y] = hexchars[(unsigned char) s[x] & 15];
??? }
? }
?str[y] = '\0';
? len= y;
?return ((char *)str);
}
?
这里的str[y]是接受到的特殊字符是否进行编码,我们只需要在if最外层判断&&str[y]!=’~’即可,修改如下:
if (((str[y] < '0' && str[y] !='-' && str[y] != '.') ||
?????(str[y] < 'A' && str[y] > '9') ||
???????(str[y] > 'Z' && str[y] < 'a' && str[y] != '_') ||
?????(str[y] > 'z'))&&str[y]!=’~’)
?
?
38.????????添加hiphop动态链接库CMake/HPHPFind.cmake
添加:
???target_link_libraries(${target} /export/dev_hphp/usr/lib/libhiredis.so)
???target_link_libraries(${target}/export/dev_hphp/usr/lib/libmongoclient.a)
???target_link_libraries(${target} /usr/lib64/libboost_thread-mt.so)
???target_link_libraries(${target} /usr/lib64/libboost_filesystem.so)
target_link_libraries(${target}/usr/lib64/libboost_program_options.so)
后面的就是动态链接库的地址
?
?
39.????????Hiphop编译错误../../../bin/libhphp_runtime.a(dynamic_table_class.cpp.o):In function `HPHP::c_MongoCursor::create(HPHP::Object, HPHP::String,HPHP::Array, HPHP::Array)':
dynamic_table_class.cpp:(.text+0x22455):undefined reference to `HPHP::c_MongoCursor::t___construct(HPHP::Objectconst&, HPHP::String const&, HPHP::Array const&, HPHP::Arrayconst&
?
报这个问题,如果存在t___construc但是编译找不到,那么清空编译目录重新编译
?
40.????????Hiphop编译错误runningexecutable /export/dev_hphp/hiphop-php_hzg/src/hhvm/hhvm-vRepo.Authoritative=true -vRepo.Commit=false -vRepo.Local.Mode=r--vRepo.Local.Path=/export/hphp_project/test//hhvm.hhbc --file test_mongo.php...
sh:/export/dev_hphp/hiphop-php_hzg/src/hhvm/hhvm:?没有那个文件或目录
如果报上述错误,那么在HPHP_HOME下执行
Cmake .
Make –j 16生成HHVM即可
?
41.????????Hiphop编译php错误当报如下错误时:
runningexecutable /export/dev/hiphop-php/src/hhvm/hhvm -vRepo.Authoritative=true-vRepo.Commit=false -vRepo.Local.Mode=r--vRepo.Local.Path=/export/hphp_project/test/hhvm.hhbc --file test_mongo.php...
sh:/export/dev/hiphop-php/src/hhvm/hhvm: No such file or directory
command failed:"/export/dev/hiphop-php/src/hhvm/hhvm -vRepo.Authoritative=true-vRepo.Commit=false -vRepo.Local.Mode=r--vRepo.Local.Path=/export/hphp_project/test/hhvm.hhbc --filetest_mongo.php"
all files savedin /export/hphp_project/test ...
running hphptook 0'00" (291 ms) wall time
?
这个是由于设置了USE_HHVM=1
这里把USE_HHVM=1环境变量清空,cmakemake?编译即可
?
?
42.????????Hiphop添加析构函数在src\compiler\statement\Class_Statement.cpp文件下outputCPPImpl是生成头文件的代码
我们这个添加析构就是给类继承Sweepable,并且在c++的析构中调用t___destruct()即可;
我们在class_Statement.cpp文件的379行添加上:
public Sweepable
也就是如下代码:
cg_printf(" : public ObjectData,publicSweepable");
?
然后我们在592行下添加如下代码:
//add hiphop __destruct functoin
???????std::set <string> ::iteratordestruct_fun=done.find("__destruct ");
???????//__destrcut exists
???????if(destruct_fun!=done.end()){
??????????????? cg_printf("public:~c_%s(){t___destruct();}\n",clsName);
???????}
上面的代码就是当类中有__destruct函数时,那么我们则在类里面添加
~c_类名(){t___destruct();}
添加c++析构函数,并调用php的析构即可;
done中保存了所有的类的声明的函数
?
?
?
43.????????hiphop?报undefinedreference to `HPHP::c_MongoDate::os_prop_table'错误当hiphop报如下错误时:
undefined reference to`HPHP::c_MongoDate::os_prop_table'
由于该类用了属性,但是未引用
在dymanic_table_class.cpp最后加入:
const ClassPropTablec_MongoDate::os_prop_table = {
?7,1,-1,-1,-1,-1,9,0,
?cpt_hash_entries+0,0,cpt_table_entries+0,cpt_static_inits
};
这个就可以了
?
?
44.????????Hiphop报段错误hphp:/export/dev/hiphop-php/src/compiler/analysis/type.cpp:82: static HPHP::TypePtrHPHP::Type::GetType(HPHP::Type::KindOf, const std::string&): Assertion`kindOf' failed.
Core dumped: Aborted
hphp failed
当编译php时报了如上错误,可能是由于system/xxx.inc内容和扩展的内容不匹配所造成的,所以检查新增的扩展和inc文件内容是否匹配
?
?
45.????????Hiphop最新版本支持包Hiphop标准的gcc版本和boost
Gcc :4.6.1
Boost:1.50
这2个是facebook正在使用的,而且编译不会出现问题
?
?
46.????????Hiphop?支持namespace修改/export/dev/hiphop-php/src/compiler/code_generator.cpp
364行的FormatLabel方法:
std::string CodeGenerator:: FormatLabel(const std::string &name) {
?//cout<<name<<"---------------------------------"<<endl;
?string ret;
?ret.reserve(name.size());
? for(size_t i = 0; i < name.size(); i++) {
???unsigned char ch = name[i];
???if ((ch >= 'a' && ch <= 'z') ||
???????(ch >= 'A' && ch <= 'Z') ||
???????(ch >= '0' && ch <= '9') || ch == '_') {
?????ret += ch;
??? }else {
?????char buf[10];
?????if(ch=='\\'){
???????snprintf(buf, sizeof(buf), "%02X",(int)ch);
?????}else{
?????snprintf(buf, sizeof(buf), "%s%02X",Option::LabelEscape.c_str(),
?????????????? (int)ch);
?????}
?????ret += buf;
??? }
? }
?return ret;
}
Option::LabelEscape.c_str()是$
FormatLabel方法是把所有不包含在a-z,A-Z,0-9或_外的所有内容前加上$并把后面的字符通过%02X转换为16进制的ASCII码
我这里修改为:
if(ch=='\\'){
???????snprintf(buf, sizeof(buf), "%02X",(int)ch);
?????}else{
?????snprintf(buf, sizeof(buf), "%s%02X", Option::LabelEscape.c_str(),
?????????????? (int)ch);
?????}
?
当不在数字、字母、下划线外的,如果字符为\\(右斜杠),那么不在其前面增加$只对其进行转义为5C,\\对应的ascii码是92
除此之外,还有在cpp中会添加上:
FORWARD_DECLARE_CLASS(类名)
所以这里也需要转义,否则找不到类:
生成FORWARD_DECLARE_CLASS的有3个地方:
(1)Src/compiler/code_generator.cpp中的
outputForwardDeclaration方法
是进行FORWARD_DECLARE_CLASS赋值的
?
(2) compiler/analysis/function_scope.cpp
outputCPPPreface该函数2184行FORWARD_DECLARE_CLASS
?
?
(3)compiler/analysis/variable_table.cpp
outputCPPGlobalVariablesHeader函数的866行FORWARD_DECLARE_CLASS
?
在生成代码后sys/ global_variables.cpp这个cpp文件中会生成FORWARD_DECLARE_CLASS代码
我们修改
compiler/analysis/variable_table.cpp的代码:
将866行代码:
????cg_printf("FORWARD_DECLARE_CLASS(%s);\n",
????????????????varType->getName().c_str());
修改为:
???????string cls_name_new=CodeGenerator::FormatLabel(varType->getName());
???????cg_printf("FORWARD_DECLARE_CLASS(%s);\n",
????????????????? cls_name_new.c_str());
首先进行一次格式化操作
?
?
47.????????Hiphop环境变量错误编译失败当hiphop编译php时,编译失败,报如下错误:
compiling andlinking CPP files...
/export/hphp_project/test/cpp/001.cpp: In function \xe2\x80\x98HPHP::VariantHPHP::pm_php$test_diff1_php(bool, HPHP::LVariableTable*,HPHP::Globals*)\xe2\x80\x99:\n/export/hphp_project/test/cpp/001.cpp:25: error:\xe2\x80\x98x_onlysee\xe2\x80\x99 was not declared in thisscope\n/export/hphp_project/test/cpp/001.cpp:28: error: expected initializerbefore \xe2\x80\x98&\xe2\x80\x99token\n/export/hphp_project/test/cpp/001.cpp:29: error:\xe2\x80\x98tmp0\xe2\x80\x99 was not declared in this scope\nmake[2]: ***[CMakeFiles/program.dir/cpp/001.cpp.o] Error 1\nmake[1]: ***[CMakeFiles/program.dir/all] Error 2\nmake: *** [all] Error 2\n
?
这是由于环境变量错误造成的,所以重新设定的HPHP_HOME和HPHP_LIB即可
?
48.????????Hiphop?多核编译在bin/run.sh中的make?后面加入-j 16 ,16是cpu数量
if [ -n "$HPHP_VERBOSE" ]; then
?make -j 16 $MAKEOPTS > /dev/tty || exit $?
else
?make -j 16 $MAKEOPTS || exit $?
Fi
?
?
49.????????Hiphop 20121224版编译错误解决当编译时抛出了如下错误:
/export/dev_hhvm/hiphop-php_hzg/src/util/asm-x64.h:360:20:error: uninitialized const 'HPHP::VM::Transl::reg::rip' [-fpermissive]
解决方法:
在$HPHP/CMake/HPHPSetup.cmake?的118行,添加-fpermissive在编译即可,?下面标红位置
set(CMAKE_CXX_FLAGS "-fno-gcse-fno-omit-frame-pointer -ftemplate-depth-60 -Wall -Woverloaded-virtual-Wno-deprecated -Wno-strict-aliasing -Wno-write-strings -W??? no-invalid-offsetof -fno-operator-names-Wno-error=array-bounds -Wno-error=switch -std=gnu++0x -Werror=format-security?-fpermissive"
?
?
50.????????hphp?生成扩展(静态编译)首先创建src/idl/xxx.idl.php,如mongo.idl.php
然后返回到src?目录下,执行:
EXT=mongo make –C idl install|update
注:
如果按照原生写的makeFile会覆盖掉,system/ext.inc?和runtime/ext/ext.h文件的内容,所以我将src/idl/MakeFile的内容覆盖system/ext.inc和runtime/ext/ext.h的内容注释掉;
内容为:
21行的:
../system/ext.inc:idl_list.php $(IDL_PHPS)
?20????@echo 'Generating $@'
?21????#$(V)$(PHP) idl_list.php inc $@
?22????$(V)touch ../compiler/builtin_symbols.cpp
?
35行的:
33 ../runtime/ext/ext.h: idl_list.php$(IDL_PHPS)
?34????@echo 'Generating $@'
?35????#$(V)$(PHP) idl_list.php ext $@
?
然后生成好后,在system/ext.inc?中加入新添加好的xxx.inc?,如mongo.inc;
如:
#include "mongo.inc"
然后在runtime/ext/ext.h中添加:
#include<runtime/ext/profile/extprofile_mongo.h>
?
添加好后,然后去$HPHP/build目录下进行编译;
由于在ext.inc?中添加了mongo.inc,所以mongo.inc的内容即为系统的内容;
在builtin_symbols.h?中即可把类,函数等信息初始化前加载在静态变量中,如:
?static const char *ExtensionFunctions[];
?static const char *ExtensionClasses[];
??static const char *ExtensionConsts[];
?static const char *ExtensionDeclaredDynamic[];
?static const char *SystemClasses[];
?static const char *HelperFunctions[];
?
编译好后,然后在system?目录下执行:
$HPHP --opts=none -t cpp -f sys -o ./gen t--input-dir . -i `find classes globals -name '*.php'`
?
即可将system/gen下的所有内容进行替换,如dymanic_table_class.cpp中的内容就会有mongo.inc中的类、变量等内容
?
然后在去$HPHP/build中进行make –j 16?编译,即可将扩展编译进去,这样扩展就编译成功和?hphp??成功耦合;
?
注意:
在生成好了system/gen下内容后,需要对ext_xxx.h对应的ext_xxx.cp中的内容进行实现,否则dymanic_table中是找不到实现的方法的,所以会报undefined reference?这样的错误
?
?
51.????????Hiphop20121224版本编译扩展undefinedreference to?错误解决方法./../../bin/libext_hhvm.a(ext_mongo.ext_hhvm.cpp.o):In function `HPHP::fg_test_hello(HPHP::VM::ActRec*)':
ext_mongo.ext_hhvm.cpp:(.text+0x1a):undefined reference to `HPHP::f_test_hello()'
../../../bin/libext_hhvm.a(ext_mongo.ext_hhvm.cpp.o):In function `HPHP::new_Mongo_Instance(HPHP::VM::Class*)':
ext_mongo.ext_hhvm.cpp:(.text+0x153):undefined reference to `HPHP::c_Mongo::c_Mongo(HPHP::ObjectStaticCallbacksconst*)'
../../../bin/libext_hhvm.a(ext_mongo.ext_hhvm.cpp.o):In function `HPHP::tg_5Mongo___construct(HPHP::VM::ActRec*)':
ext_mongo.ext_hhvm.cpp:(.text+0x211):undefined reference to `HPHP::c_Mongo::t___construct(HPHP::String const&,HPHP::Variant const&)'
../../../bin/libext_hhvm.a(ext_mongo.ext_hhvm.cpp.o):In function `HPHP::tg_5Mongo___get(HPHP::VM::ActRec*)':
ext_mongo.ext_hhvm.cpp:(.text+0x5ff):undefined reference to `HPHP::c_Mongo::t___get(HPHP::Variant)'
../../../bin/libext_hhvm.a(ext_mongo.ext_hhvm.cpp.o):In function `HPHP::tg_5Mongo___destruct(HPHP::VM::ActRec*)':
ext_mongo.ext_hhvm.cpp:(.text+0x770):undefined reference to `HPHP::c_Mongo::t___destruct()'
../../../bin/libext_hhvm.a(ext_mongo.ext_hhvm.cpp.o):In function `HPHP::tg1_5Mongo___construct(HPHP::TypedValue*, HPHP::VM::ActRec*,long long, HPHP::ObjectData*)':
ext_mongo.ext_hhvm.cpp:(.text.unlikely+0xfd):undefined reference to `HPHP::c_Mongo::t___construct(HPHP::String const&,HPHP::Variant const&)'
../../../bin/libext_hhvm.a(ext_hhvm_infotabs.cpp.o):(.rodata+0x91b8):undefined reference to `HPHP::f_test_hello()'
collect2: ld returned 1 exit status
?
生成ext?扩展后,会在runtime/ext目录下生成如:
ext_mongo.h ext_mongo.cpp这2个文件,然后在ext_mongo.cpp中添加上实现;
?
然后我们在build目录下执行make –j 16?编译;编译完毕后,我们执行bin/generated_files.sh all
命令后,然后我们生成了hhvm?和hhvm_infotabs的内容;
但是编译后出现了为引用的信息,未引用的内容是ext_mongo.cpp的方法,由于在hiphop中是在dymanic_table中引用了这些内容,如果不对dymanic_table的内容进程生成,那么只有实现,没有引用就会产生这样的错误;
所以正常流程为:
(1)????先定义idl;
(2)????定义好idl后,去src?目录下执行EXT=mongo make –C idl install|update
(3)????将src/system/mongo.inc添加到ext.inc中进行引用;
(4)????将src/runtime/ext/extprofile_mongo.h?添加到ext.h中进行引用
(5)????去build目录下执行make –j 16,添加好ext.inc后,mongo的内容就为系统的内容了,类、函数、变量、常量等均会捕获到
(6)????执行完毕后,在去执行bin/generated_files.sh all,生成hhvm.cpp,更新hhvm_infotabs.cpp等
(7)????然后再去build目录重新build,这样扩展就加入到hhvm中了
?
?
52.????????扩展模板生成类无构造函数错误解决方法当通过idl生成扩展时报了如下错误;
PHP Fatal error:? Uncaught exception 'Exception' with message'No constructor defined for class s_class' in/export/dev_hhvm/hiphop-php_hzg/src/idl/base.php:243
Stack trace:
#0 /export/dev_hhvm/hiphop-php_hzg/src/idl/test.idl.php(88):EndClass()
#1/export/dev_hhvm/hiphop-php_hzg/src/idl/idl.php(31):require('/export/dev_hhv...')
#2 {main}
?thrown in /export/dev_hhvm/hiphop-php_hzg/src/idl/base.php on line 243
这是由于没有添加构造函数造成的问题;
DefineFunction(
?array(
???"name"?? =>"__construct",
???"flags"? =>HasDocComment,
???"return" => array(
?????"type"?? => null,
???),
? ));
加上这个就可以了
53.????????生成扩展段错误,模板flags没加问题在idl.php中
对于所有的class,function.defineProperty,defineConstant的声明flags是必须的,如果不加flags,那么编译好后,会抛出段错误,在compiler/builtin_symbols.cpp:189行,所以需要注意这一点,也就是最后在189行后的cname会是空指针
?
54.????????undefined reference?错误解决方法../../../bin/libext_hhvm.a(ext_hhvm_infotabs.cpp.o):(.rodata+0x11e70):undefined reference to `HPHP::fg_test_hello(HPHP::VM::ActRec*)'
这个问题需要清空build ,重新编译
?
?
55.????????Idl模板实现接口'ifaces' => array('Iterable','Countable'),
?
IsFinal用法,类定义(idl/collection.idl.php):
BeginClass(
?array(
???'name'?? =>"VectorIterator",
???'ifaces' => array('Iterator'),
???'desc'?? => "An iteratorimplementation for iterating over a Vector.",
???'flags'? =>? IsFinal | HasDocComment,
? ));
?
?
?
?
RefVariableArguments用法(idl/file.idl.php)
DefineFunction(
?array(
???'name'?? => "fscanf",
???'desc'?? => “”,
???'flags'? =>? HasDocComment | RefVariableArguments,
??? …….
? ));
?
FunctionIsFoldable | NoEffect | NoInjection用法(idl/variable.idl.php):
DefineFunction(
?array(
???'name'?? =>"is_bool",
???'desc'?? => "Finds whetherthe given variable is a boolean.",
???'flags'? =>? HasDocComment | FunctionIsFoldable | NoEffect| NoInjection,
?? …..
? ));
?
MixedVariableArguments | ContextSensitive用法(idl/function.idl.php)
DefineFunction(
?array(
???'name'?? =>"call_user_func_async",
???'desc'?? => ".",
???'flags'? =>? HasDocComment | HipHopSpecific |MixedVariableArguments | ContextSensitive,
….
}
?
AllowIntercept用法(idl/apc.idl.php):
DefineFunction(
?array(
???'name'?? =>"apc_add",
???'desc'?? => ".",
'flags'? =>?HasDocComment | AllowIntercept,
…………….
}
?
HipHopSpecific| VariableArguments | HasOptFunction | NoProfile?用法(idl/fb.idl.php)
DefineFunction(
? array(
??? 'name'??=> "fb_call_user_func_safe",
??? 'desc'??=> "",
??? 'flags'?=>? HasDocComment |HipHopSpecific | VariableArguments | HasOptFunction | NoProfile |ContextSensitive,
??? 'opt'???=> "hphp_opt_fb_call_user_func",
? …..
? ));
?
NoDefaultSweep用法(idl/domdocument.idl.php):
BeginClass(
? array(
??? 'name'??=> "DOMDocument",
??? 'parent' => "DOMNode",
??? 'bases'?=> array('Sweepable'),
??? 'desc'??=> "",
??? 'flags'?=>? HasDocComment |NoDefaultSweep,
…
}
?
NeedsActRec用法(idl/error.idl.php):
DefineFunction(
? array(
??? 'name'??=> "debug_backtrace",
??? 'desc'??=> "debug_backtrace() generates a PHP backtrace.",
??? 'flags'?=>? HasDocComment |NeedsActRec,
?……..
??? 'taint_observer' => false,
? ));
?
56.????????idl Flags?配置functionflags:
HasDocComment
HasOptFunction??????
MixedVariableArguments
RefVariableArguments
VariableArguments
NoEffect
FunctionIsFoldable
ContextSensitive
NeedsActRec
Classflags:
Class method:
IsAbstract
IsProtected
IsPrivate
IsStatic
Class properties:
IsProtected
IsPrivate
IsStatic
?
57.????????Hiphop char?转换为Variant乱码Char * a=malloc(sizeof(char));
如a?的值为”aaaddd”
将a转为hiphop?的variant
Variant(a)
但是这样转换后,有时候会产生乱码,所以我们需要先将char?指针等内容先转换为c++的
String?,然后将string?的值转换为Variant这样就不会产生乱码了
如:
Char a[3]=”abc”;
String b=a;
Varaint c=Varaint(b);
?
58.????????Hiphop ext扩展错误提示和异常在cpp扩展代码中写入:
raise_warning(“warning content”);
?
raise_error(“error content!”);
?
59.????????设置编码Server {
DefaultCharsetName = GBK
}
?
?
60.????????Hiphop soapHiphop soap基本功能可支持,但是不支持no-wsdl模式,但是一般的情况下,一般都是使用wsdl模式;
SOAPFault php?和hiphop?抛出异常模式些许差异;但是都可以提示错误;
?
61.????????执行generated_files.sh hhvm报错当执行bin下的generated_files.sh hhvm报如下错误时
No object file to generate xxx.hhvm.cpp from,did you build first?
是因为新的扩展的.o文件不存在,所以需要重新编译可以找到该文件即可
这个内容是在generated_files.sh文件中这里实现的:
# $1 - Binary to pull symbols from
# $2 - .ext_hhvm.cpp file to build
make_hhvm()
{
?echo "$1===$2"
? [ !-f "$1" ] && check_err 1 "No object file to generate $2from, did you build first?"
? [$VERBOSE -eq 1 ] && echo "Generating $2"
?$HHVM gen_ext_hhvm.php $2 . /dev/null /dev/null "" $1
?check_err $? "Failed generating $2"
}
?
62.????????Hiphop?扩展的函数名必须是小写执行generated_files.sh hhvm
报了如下错误,因为function的名字有大写(这是有问题的)需要完善
Extension function name must be alllowercase: Ice_initialize
ext_hhvm generation failed
ERROR # 1 : Failed generating../ext/ext_ice.ext_hhvm.cpp
?
报这个错误的是:
是这个src/runtime/ext_hhvm/gen_lib.php文件中252行
if ($this->name != strtolower($this->name)){
?????echo "Extension function name must be all " .
?????????"lowercase: " . $this->name . "\n";
?????echo "ext_hhvm generation failed\n";
????exit(1);
?
生成扩展时生成的函数名称也都变为了小写是在src/idl/base.php中进行转换的
不知道为何将方法的名称都转为了小写
?
经测试,idl中的函数的命名可以为小写,因为在编译好的hhvm中,对于方法的名称不区分大小写,最终都是识别到小写
?
63.????????Hiphop Idl?设置默认值在设置idl?的参数时,最多可以有2个不设置默认值;
如果你有4个参数,你都不设置默认值,那么第三个、第四个就会报如下错误:
default argument missing for parameter 4
所以最好设置idl时,给函数的参数都设置默认值
?
64.????????HPHP::String?转换成std::StringHPHP::String是hiphop?自定义的一个String类,它不能之间强转为std::String
需要通过将HPHP::String转换成char*?然后转换为std::String
例:
Varint a;//是一个hphp:string类型
Std::string b=a.toString().data();
这样既可
?
65.????????CObjRef转成指定类型的指针bool f_memcache_set_server_params(CObjRefmemcache, CStrRef host,) {
? //将Object对象转换成指定类型
??c_Memcache *memcache_obj =memcache.getTyped<c_Memcache>();
?return memcache_obj->t_setserverparams(host, port, timeout,retry_interval,
????????????????????????????????????????status, failure_callback);
}
?
66.????????实例化hiphop?已有的hiphop类对象,并调用构造函数如:
Php?中定义了一个类:
Class A {
???????? Public$a;
???????? Public$b;
???????? Publicfunction __construct($a,$b){
?????????????????? $this->a=$a;
?????????????????? $this->b=$b
???????? }
}
?
当通过hhvm转换后,这个A的类会生成一个hiphop的类为:c_A
?
Hiphop?实例化A并且通过构造函数对其进行成员变量的封装:
Object f_getObjectClass(CVarRefv) {
Object *obj = new Object();
//string aa = "c_" + v.toString();
HPHP::CStrRef ss = v.toCStrRef();
Array* params=new Array();
?params->append(Variant("aaaaaa"));
?params->append(Variant("bbbbbb"));
/*第一个参数是类的名称如:c_A
??第二个参数是构造函数的参数,这个必须得有带参的构造函数,否则值是设置不进去的,
??而且参数是按顺序进行遍历的;
??第三个参数是对对象进行构造函数初始化
*/
Object aa=create_object(ss,*params,true);
return aa;?
}
?
在头文件中需要引入
#include<runtime/base/externals.h>
这个头文件,create_object函数在这个文件中进行声明的
?
Create_Object实现是在bytecode.cpp文件中1365行,这个是hhvm的实现
create_object在builtin_functions.cpp的1012行是对外的create_object接口函数,分支是走hhvm还是走hphp
?
67.?内存泄露问题$str =time().'.'.rand(10000, 99999) ;
define('LOG_ID', $str ) ;
?
当一个变量调用2个函数进行连接时,然后用define方式定义为常量会造成内存泄露的问题;
将常量设置为全局变量就可以解决这个问题了
?
?
68.?获取对象的成员变量值和通过类名获取类的成员Object f_icephp_defineproxy (CObjRefclassObj) {
? /*
?????????通过传入对象获取对象的成员集合
???????? Vars是以key value?保存的
? */
?Variant vars=f_get_object_vars(classObj);
? /*
?????????通过类名获取类下的所有成员名称
??? classObj->o_getClassName()获取类名的方法返回值为CStrRef在Type_object.h中
?*/
?Array varNames=f_get_class_vars(classObj->o_getClassName());
? /*
?????????遍历类成员的名称
*/
? for(ArrayIter iter(varNames); iter; ++iter) {
?????????????????? ? /*
????????????????????????????获取成员名称
?????????????????? */
?????????Variant vKey = iter.first();
?????????????????? /*
????????????????????????????根据成员名称获取对象下该成员的值
?????????????????? */
?????????cout<<vKey.toString()<<":"<<vars[vKey].toString()<<endl;;
? }
???return NULL;
}
../runtime/ext/ext_class.h
/*?通过类名获取类下的成员名称的Array集合*/
Array f_get_class_vars(CStrRef class_name);
/*
?????????通过传入对象获取对象的成员列表
?????????保存内容为:keyvalue?,key是成员名称,value是成员值
???????? Variant是返回的集合
*/
Variant f_get_object_vars(CVarRef object);
?
Ext_class.h是hiphop操作类的扩展;
?
Php?代码:
?
<?php
???class A{
???????public $a;
???????public $b;
???????public $c;
???????public function __construct($a,$b,$c){
???????????$this->a=$a;
???????????$this->b=$b;
???????????$this->c=$c;
???????}
??? }
?
???$a=new A("aaa222","bbb333","cccccc");
??? $c=newA("aaa111","bbb222","cccccc333");
?
???//echo $a;
???//print_r($a);
???//var_dump($a);
???$b=get_object_vars($a);
???$count=count($b);
???echo $count;
???var_dump($b);
???echo $b["a"];
???echo $b["b"];
???icephp_defineproxy($a);
???icephp_defineproxy($c);
?>
?
后端输出内容如下,已获取到对象值
a:aaa222|
b:bbb333|
c:cccccc|
a:aaa111|
b:bbb222|
c:cccccc333|
?
?
69.????????hiphop?抛出异常处理(1)??????简单的抛出异常处理
throw Exception(“Test throw Exception”);
或
Exception e=new Exception(“Test thorw Exception”);
调用抛出异常的方法后hiphop控制台输出:
HipHop Fatal error: Test thorw Exception
(2)??????获取php中声明的异常类,抛出异常信息
Hiphop代码:
Objectf_icephp_defineproxy(CObjRef classname) {
Objectf_icephp_defineproxy(CObjRef classname)
Array*params=new Array();
?params->append(Variant(300));
?params->append(Variant("RpcExceptionerror msg!"));
/*
通过创建动态类根据类名构造一个异常类,但是这里需要注意的是:
一般用户类前会加上c_xxx,但是Exception的用户类没有c_,直接在php
中定义的是什么类名,那么这里在创建对象时也是用什么名称,这里需要
注意,否则会找不到类
*/
Objecte=create_object("com_xx_RpcException",*params,true);
?? ? ??throwe;
return NULL;
}
?
PHP代码:
class com_xx_RpcExceptionextends Exception
{
??????? public function__construct($resultCode=0, $msg='')
??????? {
??????????????? $this->resultCode =$resultCode;
??????????????? $this->msg = $msg;
??????? }
?
??????? public function ice_name()
??????? {
??????????????? return 'com::xx::RpcException';
??????? }
?
??????? public function __toString()
??????? {
??????????? return$this->msg."|".$this->resultCode;
??????? }
?
??????? public $resultCode;
??????? public $msg;
}
?
try{
??? icephp_defineproxy($a);
???}catch(Exception $e){
??????? echo $e;
}
?
调用后在页面输出:
RpcException error msg!|300
?
?
70.????????Hiphop idl常量定义问题DefineConstant(
???array(
???????'name'? =>"IcePHP__t_int",
???????'type'? => Variant,
??? )
);
?
这里的Type只支持如下几种类型:
?case Type::KindOfBoolean:
?????case Type::KindOfInt64:
?????case Type::KindOfDouble:
?????case Type::KindOfString:
?????case Type::KindOfArray:
?????case Type::KindOfVariant:
???????cg_printf("(const char *)&%s,\n", varName.c_str());
???????break;
这个是在analyze_result.cpp?的3341行,他们都会转换成char类型,但是不能是Object类型的,否则在执行generate_files.sh的时候会报错误,而错误的原因就出现在常量问题;
?
?
71.????????Hiphop idl中不要用typeid做变量名用typeid做参数名称,在编译的时候会报错误,所以在idl中定义变量名称时不要用typeid做关键字
?
?
72.????????Hiphop?通过变量名称获取变量对象在ext_variable.cpp中的f_get_defined_vars函数获取所有的变量,返回一个Array,Array中存放的是key是变量名,value是对象
例子:
?Array?? dvs=f_get_defined_vars();
??????????????? Varianta=dvs["IcePHP__t_int"];
??????????????? Object? b=a.toObject();
??????????????? PrimitiveInfo*pi=b.getTyped<PrimitiveInfo>();
???????????????cout<<"IcePHP__t_int:"<<pi->kind<<endl;
?
73.????????hiphop?持久化对象g_persistentObjects是hiphop?定义的一个持久化对象的mapmap,是PersistentObjectStore类型,在execution_context.h中
set(const char *type, const char *name,ResourceData *obj)
set方法
type是类型
name是第二层key
obj?是继承ResourceData的类
get函数:
ResourceData *get(const char *type, constchar *name);
Type是类型:
Name是key,获取resoucedata的类型
下面是具体的例子:
?
class Ice_Communicator : publicSweepableResourceData{
???????????public:Ice_Communicator(){
??????????????? cp=NULL;
???????????};
???????????public:~Ice_Communicator(){};
???????????public:Ice::CommunicatorPtr cp;
???????????public:std::set<std::string> factoryWrapperClassSet;
???????????public:IceObjectFactoryWrapperPtr ifwp;
?
???????};
?
?
??????????????? pthread_t tid;
??????????????? tid = pthread_self();
???????????????//获取tid
???????????????????????????????????? Varianttidv=Variant((int64)tid);
??????????????? char *tidc=tidv.toString().data();
??????????????? Ice_Communicator*ic=dynamic_cast<Ice_Communicator*>(g_persistentObjects->get("ice_c",tidc));
??????????????? if(ic==NULL){
???????????????????ic=new Ice_Communicator();
???????????????????g_persistentObjects->set("ice_c",tidc, ic);
???????????????????ic->cp=Ice::initialize();
?
??????????????? }
?
74.????????Hiphop?性能问题须知编译hiphop?时如果需要debug
那么加上
cmake -DCMAKE_BUILD_TYPE=Debug .
?
但是如果加上debug后,hiphop的cpu使用率会高一倍
所以在线上正式使用的时候,需要把debug去掉,这样性能可以提高一倍
cmake .
?
75.????????编译好的二进制的hhvm找systemlib.php文件当执行hhvm找不到systemlib.php文件时,是由于没有配置HPHP_LIB环境变量,
HPHP_LIB指向的是hphp的bin目录,systemlib.php文件就在bin目录下
?
?
76.????????Php中的unset是销毁对象函数当在php代码中调用了unset函数会销毁当前对象触发析构函数;
如:
$a=new A();
Unset($a);
这样就触发了A的析构函数,销毁了该对象
$a=new A();
$a=null;
也会销毁对象
?
?
77.????????Hiphop?内存泄露总结当涉及到使用hiphop的扩展类时,需要实例化一个对象指针:
如:
Class Test:public ExtObjectData,publicSweepable{
?
}
?
那么当在代码中进行实例化,需要用hiphop内置的宏NEWOBJ
例:
Test?*test=NEWOBJ(TEST)();
这样可以控制内存,如果用自己的new Test()这样实例化,一般delete需要考虑很多因素,但是用NEWOBJ时,需要在扩展类后面继承上Sweepable类才可以回收调用析构函数,这样就匹配了,不会造成内存泄露;
NEWOBJ用法:
NEWOBJ(扩展类类名)(参数)
?
当在hiphop?自己的创建的类,那么就需要用new?和delete?进行匹配,否则会造成内存泄露;
?
在使用map时,如果是把值放入到对象中,那么map的second是存的值,这时的地址不是你的对象地址,如:
Test *test=new Test();
Std::map<std::string,Test> map;
Map[“1”]=*test;
注意,这里的map[1]存的value是test对象,而不是test这个对象的地址,当封装到map中后,map会给他分配一块独立的地址,所以再取时释放的也是map的地址,如果想用map存放上对象,并在后面释放,那么最好存对象指针
?
getTyped涉及内存泄露:
当使用getTyped进行类型转换时,getTyped中的类需要继承Sweapable,否则转换的对象不会被回收
p_cict?= iceclassobj.getTyped<c_IcePHP_class>();
?
Array和Varaint如果用new?来实例化,那么需要对其进行delete回收对象,所以一般建议去创建值,如果非要用指针,那么就要注意回收:
Array array=Array::Create();//创建Array对象
Variant v=Variant();//创建Variant对象
?
?
78.????????编码问题到底hhvm?运行报unknown Exception?
部署hiphop?的时候首先打印一下语言:
echo $LANG
?
输出为:
zh_CN.UTF-8
?
这个是正确的,如果编码为
Zh-CN.gbk
这个横线应该是下划线,否则hiphop访问时会报unknown exception错误,这个很难发现,一定要注意
?
?
79.????????共享内存对象Hiphop中的APC使用共享内存对象实现的,所以xcache也采用该模式,在hiphop中的
SharedStore类是共享存储,并且通过newConcurrentTableSharedStore(0)进行实例化的;
SharedStore定义在src\runtime\base\shared\shared_store_base.h中
ConcurrentTableSharedStore?定义在src\runtime\base\shared\concurrent_shared_store.h中
ConcurrentTableSharedStore(id)构造函数中是id?一般来说一个下标即可;
ConcurrentTableSharedStore是SharedStore的子类
例:
SharedStore m_store = newConcurrentTableSharedStore(0) ;
//存值:
m_store ->store( name, value, ttl, true)
//具体实现:?
/*
virtual bool store(CStrRef key, CVarRefval, int64 ttl,
???????????????????? bool overwrite = true
*/
//取值
m_store ->get(name, v);
?
详细可见源码;
?
?
80.????????Memcached超时问题解决安装libmecached需要在1.0.1以上,目前安装的是1.0.5
安装后,然后将包替换到/export/dev_hhvm/usr下包括头文件和so文件
然后重新编译
用ldd build/src/hhvm/hhvm |grep memcached查看
libmemcached.so.9 =>/export/dev_hhvm/usr/lib/libmemcached.so.9
如果是9就对了,如果是7那么就是0.49版本的,老版本的不支持超时;
还有一点就是
$m->setOption(Memcached::OPT_RECV_TIMEOUT,1000);
$m->setOption(Memcached::OPT_SEND_TIMEOUT,1000);
$m->setOption(Memcached::OPT_RETRY_TIMEOUT,300);
$m->setOption(Memcached::OPT_CONNECT_TIMEOUT,1);
?
$m->addServer('10.1.2.3', 11211);
?
setOption?设置需要在addServer之前才可以生效,在addServer后不生效
?
81.????????添加hhvm runtime option在runtime_option.cpp中定义静态变量,设定初值
? //第一层
? Hdfmysql = config["MySQL"];
? //第二层,MySQLReadOnly是静态变量,ReadOnly是mysql下的值
??MySQLReadOnly =mysql["ReadOnly"].getBool();
?
调用时RuntimeOption:: MySQLReadOnly调用就可以获取了
?
Src/runtime/base/runtime_option.cpp
82.????????Freetds查找etc配置问题Hhvm应用freetds时,需要找到他的动态链接库libsybdb.so;
libsybdb.so库可以放到任意位置,但是freetds的etc需要在一个已经安装的目录下,而etc也需要是这个目录下安装好的lib下的库才可以,所以有如下2种方式配置:
(1)??????配置环境变量
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/freetds0.82/lib??
红色部分是freetds?的动态链接库位置(也就是已经安装的freetds位置)
(2)??????设置动态链接库
echo “/usr/local/freetds0.82/lib??” > /etc/ld.so.conf.d/hhvm.conf
ldconfig
?
这时候查看ldd hhvm|grep libsydbd.so就可以看到相应的路径了;
?
Freetds安装方法:
./configure--prefix=/usr/local/freetds0.82??--enable-msdblib?--with-tdsver=5.0
?
?
83.????获取cpu核心数量Process::GetCPUCount();
Src/util/process.h
?
?
MachineInfo类是机器信息在
Src/runtime/ext/ext_hotprofiler.cpp中
?
修改默认的ThreadCount数量:
默认hhvm中ThreadCount数量为50,在runtime_option.cpp中
//修改为默认cpu核数的一倍*2
int RuntimeOption::ServerThreadCount=50;//101行?定义变量
int RuntimeOption::ServerThreadCount = Process::GetCPUCount()<<1
….
ServerThreadCount =server["ThreadCount"].getInt32(50);//717行intcpucount=Process::GetCPUCount()<<1;
ServerThreadCount =server["ThreadCount"].getInt32(cpucount);//赋值操作
?
84.????????Hdf的getBool问题如:
MySQL {
???????ReadOnly = false
}
这里ReadOnly = false后面不要加分号,如果加了分号后,那么则会匹配为true
Hiphop的getBool的逻辑是不是0,false,no,off就是true
boolHdf::getBool(bool defValue /* = false */) const {
? const char *v = get();
?? //如果v是空指针,返回false
? if (v == nullptr) return defValue;
? //一般存在值即为true,因为不可能0,false,no,off共存,并且v这里永远为true,????????????? //因为strcmp不配置为非0,
? return *v && strcmp(v, "0")&&
??? strcasecmp(v, "false") &&strcasecmp(v, "no") && strcasecmp(v, "off");
}
?
?
?
85.????????获取网络传输对象Transport *transport =g_context->getTransport();
transport->sendString (“test”,200);
第一个是内容,第二个是http_code
g_context是线程内部的上下文对象;
?
?
86.????????___autoload?传入的参数为小写解决方法Test_static.php:
<?php
function __autoload($name)
{
???????echo “className:”.$name."===\n";
???????require $name.".php";
???????//require "ConsultationConstract.php";
}
?$timeout = ConsultationConstract::$GETCONSULTATION['timeout'];
?echo? $timeout;
?
?>
?
ConsultationConstract.php
<?php
?class ConsultationConstract {
???????public static $GETCONSULTATION = array (
??????????????? 'timeout' => 3600
???????);
?? }
?>
?
默认的hhvm输出??????? echo “className:”.$name."===\n";
是小写的consultationconstract;
但我们需要的是ConsultationConstract;
?
目前解决方式是:
将compiler\expression\static_class_name.cpp的updateClassName()
的?
??m_className= Util::toLower(className);
修改为:
???m_className =className;
?
默认情况下,类名转换为了小写,但是小写后,到了authLoad函数时:
/src/runtime/base/builtin_functions.cpp +1958实现的:
Array params(ArrayInit(1,ArrayInit::vectorInit).set(className).create());
传参数,这里就传入了小写的了,但是实际我们需要的是原始的,可是在hhvm的Class和?ClassInfo类中都没有原始的类名了;
上面的m_className修改后,有几处还是有对m_className进行转小写操作的,我们可以来分析一下;
1)????????这里起的是对比作用,所以无影响
类似这种的
Class_constant_expression.cpp:204(src\compiler\expression):???hash_string(Util::toLower(m_className).c_str(), m_className.size());
2)????????更新m_className
resolveStatic?函数:
voidStaticClassName::resolveStatic(const string &name) {
…..
? m_className =Util::toLower(name);
}
resolveClass函数:
ClassScopePtrStaticClassName::resolveClass() {
……..
? } else if (m_parent) {
??? if (ClassScopePtr self =scope->getContainingClass()) {
????? if (!self->getOriginalParent().empty()){
??????? m_className =Util::toLower(self->getOriginalParent());
?? ……..
????? }
??? }
?? ?? ……
}
?
resolveStatic只有1个调用
resolveClass?是在存在基类时进行调用,但是即时更新了,也都是小写状态,对于查找什么的影响不大;
?
所以目前暂时用这种解决,以后有好的方法再进行研究;
?
?
87.????????Nginx proxy+rewrite到hhvm上?request_uri问题Php代码:
$uri = $_SERVER['REQUEST_URI'];
echo $uri;
?
php url重写规则(nginx):
rewrite ^([^\.]*)/testuri\.html$ $1/index.php?mod=Testhzg&action=test5last;
?
proxy配置:
proxy_pass????? http://hhvms;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For$remote_addr;
?
正常情况下nginx + rewrite+fastcgi的输出结果:
testuri.html
?
而通过proxy到hhvm上的输出结果为:
index.php?mod=Testhzg&action=test5
?
显然php是rewrite后的结果,而hhvm是rewrite前的结果(就是原始路径)
如果要是想要hhvm+proxy也有这样的效果,那么可以这么搞:
Nginx中不进行rewrite,只进行proxy,然后由hhvm进行rewrite,然后就可以实现hhvm的request_uri也是rewrite后的结果了;
但是这样唯一的问题可能就是造成日志的问题了;
?
?
88.????????Cmake的gcc?版本问题解决当使用cmake ..时
-- The C compiler identification is GNU4.4.6
-- The CXX compiler identification is GNU4.4.6
-- The ASM compiler identification is GNU
-- Found assembler: /usr/bin/cc
-- Check for working C compiler:/usr/bin/cc
-- Check for working C compiler:/usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler:/usr/bin/c++
-- Check for working CXX compiler:/usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- CMAKE_PREFIX_PATH was missing,proceeding anyway
-- Performing Test HAVE_GCC_46
-- Performing Test HAVE_GCC_46 – Failed
报了如上内容,是gcc版本低,这里提供了一条语句/usr/bin/cc
也就是这里判断版本是通过cc判断的,我安装了gcc 4.6.3然后在bin的目录下cp gcc cc
然后配置环境变量:
exportPATH=/export/files/gcc-4.6.3/bin:$PATH
就可以识别了,gcc-4.6.3/bin需要在前面,覆盖旧path中的cc路径
?
?
89.????????Hiphop libevent打补丁失败解决git clonegit://github.com/libevent/libevent.git
cd libevent
git checkoutrelease-1.4.14b-stable
checkout有些问题,需要这么改:
git checkout –b 1.4.14b release-1.4.14b-stable
git checkout –b <branch> <tag>
?
cat../hiphop-php/hphp/third_party/libevent-1.4.14.fb-changes.diff | patch -p1
?
如果这样打包后还是有错误,打补丁失败,请查看服务器是否可以连接外网,我之前的问题是服务器不可以连接外网造成的
?
然后在可以上外网的机器上打好补丁copy过去,就可以直接编译用了
?
90.????????Libevent keepalive内存泄露问题解决在libevent下的http.c中:
位置为2319行下面加入一行:
???????? req->userdone= 1 ;
即可;
static void
evhttp_handle_request(struct evhttp_request*req, void *arg)
{
???????? structevhttp *http = arg;
???????? structevhttp_cb *cb = NULL;
?
???????? event_debug(("%s:req->uri=%s", __func__, req->uri));
???????? if(req->uri == NULL) {
?????????????????? event_debug(("%s:bad request", __func__));
?????????????????? if(req->evcon->state == EVCON_DISCONNECTED) {
??????????????????????????? /*liulei edit ????
???????????????????????????????????? solvekeepalive memery leak
???????????????????????????????????? huzhiguangadd note
??????????????????????????? */
??????????????????????????? req->userdone = 1;
???????????????????????????
??????????????????????????? evhttp_connection_fail(req->evcon,EVCON_HTTP_EOF);
?????????????????? }else {
??????????????????????????? event_debug(("%s:sending error", __func__));
??????????????????????????? evhttp_send_error(req,HTTP_BADREQUEST, "Bad Request");
?????????????????? }
?????????????????? return;
???????? }
?
91.????????Pcre问题<?php
$pattern = '/^\/$/u' ;
$case = '' ;
$pathInfo = '/' ;
if(preg_match($pattern.$case,$pathInfo,$matches)){
???????echo "1111111111 $matches<br/>" ;
???????var_dump($matches) ;
} else {
???????echo "2222222222<br/>" ;
}
?>
?
当运行hhvm的时候,报了如下错误:
HipHop Warning: Compilation failed: thisversion of PCRE is compiled without UTF support at offset 0
?
这是由于编译pcre的时候没有添加支持utf-8的选项,在编译的时候加上该选项即可:
./configure --enable-utf
?
92.????????直接应用bytecode设置Authoritative为true
Repo {
?Authoritative = true
?Central {
?????Path = /export/servers/hhvm-1.1/repo/hhvm.hhbc.sq3
??? }
}
?
?
93.????????Libmemcached版本更新更新hhvm的libmemcached版本:
默认的wiki版本是0.49:
更新1.0.5:
将include和lib一起cp到usr下,然后编译,编译好后,用:
Ldd hhvm|grep libmemcached
/export/dev_hhvm/usr/lib/libmemcached.so.9
是.9其实更新每个包下的libmemcached.so这个包到usr/lib下就可以;
?
更新1.0.17:
Include还是用1.0.5的,然后把1.0.17的libmemcached.so拷贝到/usr/lib下编译即可;
然后:
Ldd hhvm|grep libmemcached
/export/dev_hhvm/usr/lib/libmemcached.so.11
.11就是1.0.17的包了
?