PHP转换农历C扩展开发php教程

本文主要是为了熟悉php扩展开发,开发一个农历扩展貌似并没有什么luan用。php成功的原因之一是他拥有强大的扩展,并且能够让开发者灵活的开发自己的php扩展。致力于成为一个lnmpstackexpert的我(一不小心又装b了),当然不能错过,要学习专研的知识还有很多很多!!

先定义一个函数定义文件,比thrift的IDL文件要简单的多。函数定义文件定义扩展对外提供的函数原型。一般格式是一个函数一行。函数定义需要指定返回值和传入参数的类型,可以包括:bool,float,int,array等。农历算发的函数定义文件如下:

stringdatetolunar(intyear,intmonth,intday);

当然也可以在同一个函数定义文件中定义多个函数,也可以定义一个类,这样就能够生成对应的函数类扩展骨架。比如:

classLunar{

}

在PHP的源码目录下的ext/目录下有ext_skel脚本。用它可以根据刚刚定义的农历扩展函数定义文件lunar.skel生成扩展骨架。

~#./ext_skel–extname=datetolunar–proto=lunar.skel

extname表示生成的扩展名字,执行之后就会在ext/目录下生成datetolunar目录。

tigerphp-5.6.17/ext/datetolunarls[14:44:36]CREDITSEXPERIMENTALconfig.m4config.w32datetolunar.cdatetolunar.phpphp_datetolunar.htests

为了使扩展能够被编译,需要修改其中的config.m4文件,去掉虾面几行的注释(即dnl)

PHP_ARG_WITH(datetolunar,fordatetolunarsupport,

dnlMakesurethatthecommentisaligned:

[–with-datetolunarIncludedatetolunarsupport])

dnlOtherwiseuseenable:

PHP_ARG_ENABLE(datetolunar,whethertoenabledatetolunarsupport,

[–enable-datetolunarEnabledatetolunarsupport])

如果没有引用任何外部的C库的话,就不需要过多更改了。否则可能需要了解下这些

PHP_ADD_INCLUDE

PHP_ADD_LIBRARY_WITH_PATH

PHP_SUBST

PHP_NEW_EXTENSION

具体用法google下就好。

现在就已经可以编译这个扩展到你的PHP了(虽然并没有什么功能)。我一般会选择动态编译的方式,大部分开源的PHP扩展,我也会用这种方式,因为简单。

~#phpize

~#./configure–with-php-config=/opt/php/bin/php-config

~#make

~#makeinstall

之后就会生成datetolunar.so文件,添加到php.ini中添加extension=datetolunar.so,就可以尝试调用这个扩展了。生成的骨架代码中有测试扩展的PHP文件,检查扩展是否成功编译到PHP。

tigerphp-5.6.17/ext/datetolunarphpdatetolunar.php[14:31:26]

Functionsavailableinthetestextension:

confirm_datetolunar_compiled

datetolunar

Congratulations!Youhavesuccessfullymodifiedext/datetolunar/config.m4.ModuledatetolunarisnowcompiledintoPHP.

介绍了PHP扩展的开发流程之后,我们看看如何实现一个农历扩展。我们可能需要先大概了解一下农历算法。

农历算发基础知识

–算法系列之二十:计算中国农历(一)

–算法系列之二十:计算中国农历(二)

打开datetolunar.c文件能够看到如下的hex_lunar定义。

staticinthex_lunar[]={

0x04bd8,0x04ae0,0x0a570,0x054d5,0x0d260,0x0d950,0x16554,0x056a0,0x09ad0,0x055d2,

0x04ae0,0x0a5b6,0x0a4d0,0x0d250,0x1d255,0x0b540,0x0d6a0,0x0ada2,0x095b0,0x14977,

….

};

其中每一个16进制的数字表示是从1900年~2050年的所有农历数据信息,把16进制转换成2进制,每一部分表示如下

1-4:表示当年有无闰年,有的话,为闰月的月份,没有的话,为0。

5-16:为除了闰月外的正常月份是大月还是小月,1为30天,0为29天。

注意:从1月到12月对应的是第16位到第5位。

17-20:表示闰月是大月还是小月,仅当存在闰月的情况下有意义。

举个例子:

1980年的数据是:0x095b0

二进制:00001001010110110000

表示1980年没有闰月,从1月到12月的天数依次为:30、29、29、30、29、30、29、30、30、29、30、30。

1982年的数据是:0x0a974

000010100100101110100

表示1982年的4月为闰月,即有第二个4月,且是闰小月。

从1月到13月的天数依次为:30、29、30、29、29(闰月)、30、29、29、30、29、30、30、30。

由于刚开始学习写PHP扩展,不太熟悉。我选择先写完并且调试好功能之后,再把代码复制到PHP扩展中。C语言debug,推荐使用cgdb,能够边看代码边debug,比gdb方便很多。

编译

~#gcc-glunar.c-olunar

使用cgdb调试

~#sudocgdblunar

break–设置断点

run–运行程序

print–打印变量

continue–继续执行

PS:如果打印的数组很长,print被简写的话,可以在gdb中通过

>>setprintelement0

来设置。

C代码写完并且没问题之后,准备迁移到PHP的扩展中。在之前使用ext_skel脚本生成的骨架代码datetolunar.c中,有自动生成的C函数PHP_FUNCTION(datetolunar)的定义。

/*{{{protostringdatetolunar(intyear,intmonth,intday)

;*/

PHP_FUNCTION(datetolunar)

{

intargc=ZEND_NUM_ARGS();

longyear;

longmonth;

longday;

if(zend_parse_parameters(argcTSRMLS_CC,“lll”,&year,&month,&day)==FAILURE)return;

php_error(E_WARNING,“datetolunar:notyetimplemented”);

/*}}}*/

为了获得函数传递的参数,可以使用zend_parse_parameters()API函数。下面是该函数的原型:

zend_parse_parameters(intnum_argsTSRMLS_DC,char*type_spec,…);

第一个参数是传递给函数的参数个数。通常的做法是传给它ZEND_NUM_ARGS()。这是一个表示传递给函数参数总个数的宏。第二个参数是为了线程安全,总是传递TSRMLS_CC宏。第三个参数是一个字符串,指定了函数期望的参数类型,后面紧跟着需要随参数值更新的变量列表。因为PHP采用松散的变量定义和动态的类型判断,这样做就使得把不同类型的参数转化为期望的类型成为可能。例如,如果用户传递一个整数变量,可函数需要一个浮点数,那么zend_parse_parameters()就会自动地把整数转换为相应的浮点数。如果实际值无法转换成期望类型(比如整形到数组形),会触发一个警告。

了解这些之后,复制写好的C代码到函数中。需要做的只是再让PHP返回我们想要的结果就好。

这里返回一个字符串,我们用到的函数是RETURN_STRING

char*ret=lunar_output;RETVAL_STRINGL(lunar_output,strlen(ret),1);

这是直接返回了一个静态字符串,如果最后一个参数设为0,会导致php在free这个字符串的时候出错。因为PHP是类型安全的脚本语言,对于RETURN_STRINGL或是RETURN_STRING返回的字符串,php会在适当的时候free掉,所以程序员要保证返回的字符串在堆里,能够free掉,这就是为什么动态分配就没事的原因。而:

char*ret=“helloworld”;RETURN_STRINGL(ret,strlen(ret),0);

这是直接返回了一个静态字符串,导致PHP在free这个字符串的时候出错。RETURN_STRINGL和RETURN_STRING最后一个参数,如果是1,表示对第一个参数中的字符串在堆里复制一份返回,这样就没问题了。

这样就完成了我们的PHP农历扩展。编译成功!!!(当然make的时候,可能会有问题,逐一解决就好)

tigerwork/github/php-lunar-extensionphp-r“echodatetolunar(2016,2,27);”[14:47:19]丙申[猴]年正月二十%

OK,Good~

实现同样功能的农历转换代码。第一个是php实现的农历函数,第二个是我们刚刚实现的PHP扩展,都执行10000次,性能提高了大概86倍(略激动~)。

tigerwork/github/php-lunar-extensionphptest.php[18:28:06]

>>Excutephpfunction.

1.7234871387482

>>Excutephpextensionfunction.

0.022943019866943

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

THE END
1.万年历查询日历查询农历查询农历日历老黄历万年历表中华万年历 本机时间2024-12-0223:59:26 2024-12-0215:59:26 格林威治标准时间https://qq.ip138.com/day/
2.中国农历年份,rpa,机器人,自动化日历网万年历_日历网1 天前?·?日历网提供的万年历主要包含万年历查询表,万年历1900-2099年日历,还有一些相关查询,如:阴阳历转换,生辰八字查询,生日查星座等功能。更多内容请查看https://www.rili.com.cn/wannianli/ 至此千百年来,中国传统历——汉历(农历)所采用得干支纪年方法,与皇帝年号纪年一样以新年https://wdlinux.cn/html/zonghe/20241128/20015.html
3.农历转换农历 十一月大 初一日甲辰年 乙亥月 己亥日 壬申时回历(伊斯兰历)1446年5月29日 朔14:21 公元年月大 公元2024年 农历甲辰年(龙年) 日 一 二 三 四 五 六 1●十一月大 2初二 3初三 4初四 5初五 6大雪 7初七 8初八 9初九 10初十 11十一 12十二 13十三 14十四 15○十五 16十六 17十七 18十八 19https://www.gcti.edu.cn/time/Cal.htm
4.农历是阴历还是阳历转换农历俗称阴历,但实际上是由于农历本身含有节气概念,所以农历是阴阳合历,取月相的变化周期即朔望月为月的长度,参考太阳回归年为年的长度,通过设置二十四节气以及闰月以使平均历年与回归年相适应。农历和阳历没有确定的转换公式,但是可以通过查找万年历进行转换。农历和http://m.15tqc.com/show1048661/
5.国历和农历怎么转换6、国历与农历的换算公式 求教高人!!! 你指的是公历与农历的换算公式吧?这个算法复杂,我可以提供C或C++的API函数给你,不知道你是用什么语言来编的? 7、转换农历国历 网友分享:你好,国历1997.13,转换为农历是1997年1月7日,星星期四;国历1997.1,转换为农历是1996年12月24日,星期六。 https://www.105188.com/sh/618011.html
6.身份证农历日期计算法生日揭秘农历转换身份证10月12日对应的农历日期,揭秘农历生日计算法_身份证 农历日期 计算法 生日揭秘 农历转换_易学品鉴http://m.emotion123456.com/tags-62138.html
7.用C#编写19002100年阴历阳历转换程序本人在学习C#编程的过程中,通过使用天文台公布的1900-2100年阴历大小月数据,参考网站大神的案例,将其内置入程序中。运行程序,即可查询1900至2100年间任意一天的农历及干支。输入8位日期如“20240801”即可查询,如直接输入1900至2100间的4位年份数字,则显示当年一年的公历农历清单对照清单。 https://blog.csdn.net/Aleck6364/article/details/144155038
8.日历算法原理日历算法原理的内容摘要:一、公历转换农历的算法公历(GregorianCalendar)与农历(ChineseLunarCalendar)的转换关系不是一个简单的公式就可以完成,其中的转换比较复杂,原因是农历的制定相当复杂,是根据天文观测进行指定的。比较常https://m.360docs.net/doc/b215809652.html
9.asp公历转农历asp公历转农历公历转农历js*这里就是农历转换表的数据,每100一更新 DATA: BEGIN OF R_NONGLIDATA, NAME TYPE I, END OF R_NONGLIDATA *这里输入日期,是公历日期 PARAMETER P_DATUM LIKE SY-DATUM . START-OF-https://cloud.tencent.com/developer/information/asp%20%E5%85%AC%E5%8E%86%E8%BD%AC%E5%86%9C%E5%8E%86
10.免费阴历阳历转换在线工具网(zxgj.cn)阴阳历换算,农历是中国的一种传统历法,又称夏历,民间也称阴历,经常有问题农历是阴历还是阳历?农历就是阴历,阴历阳历转换在线工具提供两种历法之间的转换算法。https://www.zxgj.cn/g/yinyangli
11.阳历转化成农历法.docxC++中怎样将阳历转化成农历已关闭20[标签:C++,阳历,农历]小A角、2011-05-0311:06推荐答案一、原理篇公历转换农历的算法公历(GregorianCalendar)与农历(ChineseLunarCalendar)的转换关系不是一个简单的公式就可以完成,其中的转换比较复杂,原因是农历的制定相当复杂,是根据天文观测进行指定的。比较常用并且比较简单的公历转https://m.renrendoc.com/paper/308154963.html
12.一种公历到农历日期转换算法的实现郑丽丽谢磊李清宝一种公历到农历日期转换算法的实现 摘要 本文主要从单片机软件实现角度介绍一种公历到农历转换的算法思想,算法采用MCS-51指令系统实现。并给出程序流程图,另外对二十四节气和生肖算法也做详细介绍。 著录项https://www.zhangqiaokeyan.com/academic-journal-cn_microcomputer-information_thesis/0201243212509.html
13.阳历与农历转换的算法,,CIO之家阳历与农历转换的算法 下面是一个关于VB的农历算法 '日期数据定义方法如下 '前12个字节代表1-12月为大月或是小月,1为大月30天,0为小月29天; '第13位为闰月的情况,1为大月30天,0为小月29天; '第14位为闰月的月份,如果不是闰月为0,否则给出月份,10、11、12分别用A、B、C来表示,即使用16进制;http://km.ciozj.com/Detail.aspx?AI=48791
14.一种公历到农历日期转换算法的实现本文主要从单片机软件实现角度介绍一种公历到农历转换的算法思想, 算法采用MCS-51 指令系统实现。并给出程序流程图,另外对二十四节气和生肖的算法也做详细介绍。关键词:单片机;MCS-51 指令系统Abstract: This paper introduces the realization and algorithm of the transform between Gregorian calendar and lunar https://m.elecfans.com/article/39160.html
15.python实现的阳历转阴历(农历)算法Flex公历转农历算法 Flex公历转换成农历的类(参考C++版本)。 使用方式: new ChineseDate(new Date()).date 输出公历日期对应的农历格式。 上传者:liu_you时间:2009-12-25 Python实现公历(阳历)转农历(阴历)的方法示例 本文实例讲述了Python实现公历(阳历)转农历(阴历)的方法。分享给大家供大家参考,具体如下: 两https://www.iteye.com/resource/weixin_38721119-13777616
16.公历转换农历的算法(JavaScript).docx公历转换农历的算法(JavaScript).docx 关闭预览 想预览更多内容,点击免费在线预览全文 免费在线预览全文 阴历阳历转换using using using using using using using using using using using namespace { { { Main(System.DateTime.Now); GetChunJie(2006); } Web Form Designer generated code { { { // // /https://max.book118.com/html/2021/1207/8101016141004052.shtm
17.java新历转农历mob649e816347dd的技术博客农历是中国传统的历法,也被称为阴阳历或旧历。与公历(也称为阳历或新历)不同,农历基于月相和太阳运行周期来计算日期。在Java中,我们可以使用一些算法和库来将公历日期转换为农历日期。本文将介绍如何使用Java实现新历转农历的功能。 1. 公历和农历的区别 https://blog.51cto.com/u_16175495/6889573
18.公历农历的转换器理想股票技术论坛转换公历和农历日期,简单易用的日历转换工具。 公历农历转换计算公式详解:如何准确进行日期转换 [股票软件指标公式技术交流] 贺志辉 2024-8-4 相关标签:公历农历转换计算方法 农历和公历转换公式 公历和农历转换日期 农历与公历转换算法 公历农历的转换器 阅读106 回复0 赞0 https://www.55188.com/tag-thread-9104980-1.html