首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 开源软件 >

hiphop 1.0 开发有关问题总结 原创-胡志广

2013-09-28 
hiphop 1.0 开发问题总结 原创-胡志广???Access {?????* {???????File /export/hphp_project/xxx.xxx.com

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支持Iterator

extern 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? debug

cmake -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 soap

Hiphop 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::String

HPHP::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的包了

?

热点排行