【临时解决】php int 32 64,关于64位PHP仍然使用32位数字的问题「建议收藏」

【临时解决】php int 32 64,关于64位PHP仍然使用32位数字的问题

大家好,又见面了,我是全栈君。

首先,我们知道有两个常量。PHP_INT_MAX和PHP_INT_SIZE。

根据PHP官方手册所说,整型数的字长和平台有关,尽管通常最大值是大约二十亿(32 位有符号)。64 位平台下的最大值通常是大约 9E18。PHP 不支持无符号整数。Integer 值的字长可以用常量 PHP_INT_SIZE来表示,自 PHP 4.4.0 和 PHP 5.0.5后,最大值可以用常量 PHP_INT_MAX 来表示。

但是,当我们在Windows下使用64位PHP(版本5.6.4和5.2.17)的时候,PHP_INT_SIZE为4,PHP_INT_MAX为2^31-1。与之相反的是,如果在Linux下使用64位PHP,PHP_INT_SIZE为8,PHP_INT_MAX为2^63-1。PHP Bugs官方也有这么一条BUG报告:

https://bugs.php.net/bug.php?id=64863

【临时解决】php int 32 64,关于64位PHP仍然使用32位数字的问题「建议收藏」 

以下是我的输出

D:\Website\IIS>cat int.php

echo 'PHP_VERSION = ' . PHP_VERSION . "\n";

echo 'PHP_INT_MAX = ' . PHP_INT_MAX . "\n";

echo 'PHP_INT_SIZE = ' . PHP_INT_SIZE . "\n";
D:\Website\IIS>php int.php

PHP_VERSION = 5.6.4

PHP_INT_MAX = 2147483647

PHP_INT_SIZE = 4
D:\Website\IIS>php --version

PHP 5.6.4 (cli) (built: Dec 17 2014 13:23:31)

Copyright (c) 1997-2014 The PHP Group

Zend Engine v2.6.0, Copyright (c) 1998-2014 Zend Technologies

with Xdebug v2.2.7, Copyright (c) 2002-2015, by Derick Rethans

为什么呢?

还是查代码。

我们可以在PHP的main/main.c中查到

REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS);

嗯,那看来和C语言的long长度有关。那应该是编译器的问题了。

我们知道,PHP在Windows下用的VC++编译器。那试试看咯。

先上代码

#include 

using namespace std;

int main() {

cout <

cout <

cout <

return 0;

}

首先是在x86下编译的结果

Z:\>cl /EHsc int.cpp && int

Microsoft (R) C/C++ Optimizing Compiler Version 17.00.60610.1 for x86

Copyright (C) Microsoft Corporation.  All rights reserved.

int.cpp

Microsoft (R) Incremental Linker Version 11.00.60610.1

Copyright (C) Microsoft Corporation.  All rights reserved.

/out:int.exe

int.obj

int (size = 4) max = 2147483647

long (size = 4) max = 2147483647

llong (size = 8) max = 9223372036854775807

再用64位编译器编译吧。

Z:\>cl /EHsc int.cpp && int

Microsoft (R) C/C++ Optimizing Compiler Version 17.00.60610.1 for x64

Copyright (C) Microsoft Corporation.  All rights reserved.

int.cpp

Microsoft (R) Incremental Linker Version 11.00.60610.1

Copyright (C) Microsoft Corporation.  All rights reserved.

/out:int.exe

int.obj

int (size = 4) max = 2147483647

long (size = 4) max = 2147483647

llong (size = 8) max = 9223372036854775807

嗯,很好,我们用g++编译器编译呢?

$ g++ -v

Using built-in specs.

COLLECT_GCC=g++

COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/lto-wrapper.exe

Target: x86_64-pc-cygwin

Configured with: /cygdrive/i/szsz/tmpp/cygwin64/gcc/gcc-4.8.3-2/src/gcc-4.8.3/configure --srcdir=/cygdrive/i/szsz/tmpp/c

ygwin64/gcc/gcc-4.8.3-2/src/gcc-4.8.3 --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --libexecdi

r=/usr/libexec --datadir=/usr/share --localstatedir=/var --sysconfdir=/etc --libdir=/usr/lib --datarootdir=/usr/share --

docdir=/usr/share/doc/gcc --htmldir=/usr/share/doc/gcc/html -C --build=x86_64-pc-cygwin --host=x86_64-pc-cygwin --target

=x86_64-pc-cygwin --without-libiconv-prefix --without-libintl-prefix --enable-shared --enable-shared-libgcc --enable-sta

tic --enable-version-specific-runtime-libs --enable-bootstrap --disable-__cxa_atexit --with-dwarf2 --with-tune=generic -

-enable-languages=ada,c,c++,fortran,lto,objc,obj-c++ --enable-graphite --enable-threads=posix --enable-libatomic --enabl

e-libgomp --disable-libitm --enable-libquadmath --enable-libquadmath-support --enable-libssp --enable-libada --enable-li

bgcj-sublibs --disable-java-awt --disable-symvers --with-ecj-jar=/usr/share/java/ecj.jar --with-gnu-ld --with-gnu-as --w

ith-cloog-include=/usr/include/cloog-isl --without-libiconv-prefix --without-libintl-prefix --with-system-zlib --libexec

dir=/usr/lib

Thread model: posix

gcc version 4.8.3 (GCC)

sx@zsx-pc /cygdrive/z

$ g++ int.cpp -o int & ./int

[1] 25508

int (size = 4) max = 2147483647

long (size = 8) max = 9223372036854775807

llong (size = 8) max = 9223372036854775807

比较一下这两个编译器long的size和max,就能知道为什么在老版本PHP中INT_MAX的值不一样了。

REGISTER_MAIN_LONG_CONSTANT(“PHP_INT_SIZE”, SIZEOF_ZEND_LONG, CONST_PERSISTENT | CONST_CS);

所以,PHP7中,应该不会再出现这个问题了

Windows系统下64位PHP中PHP_INT_MAX为32位

相信很多在Windows环境开发的人都遇到一个问题,就是从数据库里取出的int值比64位PHP里面的int值大,导致用intval过滤之后,数值不准确。

Mysql中int分有符号和无符号,有符合的最大值为:2147483647 ,无符号的最大值为:4294967295。

理论上64位的PHP的PHP_INT_SIZE是:8 ,PHP_INT_MAX是:9223372036854775807。

实际上在Linux系统下64位PHP的PHP_INT_MAX的值是:9223372036854775807 ,但是在Windows系统下输出64位PHP的PHP_INT_MAX的值却是:2147483647。

通过查看PHP源码中PHP_INT_SIZE的定义:

1

REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE"sizeof(long), CONST_PERSISTENT | CONST_CS);

可以看到PHP_INT_SIZE的大小是与C语言的long类型长度一样的

PHP在Windows平台是用VC++编译的,在Linux平台是用g++编译的。查了一下关于这两个编译器在64位环境的资料:

VC++(64位) g++(64位)
int 4 4
long 4 8
long long 8 8

原来在64位编译环境中VC++和g++的long类型长度是有差别的。所以Windows下64位的PHP的int会比Mysql中无符号的int小。

在不升级php版本的情况下,如何解决这个问题呢?临时改动项目:

在框架中将

return PHP_INT_MAX  > 2147483647;
改为

return PHP_INT_MAX +1 > 2147483647;

【临时解决】php int 32 64,关于64位PHP仍然使用32位数字的问题「建议收藏」

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/111468.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Oracle insert all 详解

    Oracle insert all 详解文章目录1概述2insert的两种形式2.1insertfirst2.2insertall3数据一致性(同时插入)2.1验证:insertinto数据不一致2.2验证:insertall数据一致1概述1.作用:’正确、高效’的将’同一批数据’插入至’不同的表’中2.好处(1)’正确’:避免数据差异(2)’高效’:优于写多个insertinto(因为无论插入多少张表,’主表’只会被读取一次)3.场景,若需求:将表t中

  • 包含负数的二进制补码的加减运算叫什么_负数的补码怎么求

    包含负数的二进制补码的加减运算叫什么_负数的补码怎么求本篇文章是我的第一篇博客,用于帮助那些和我一样处于迷茫中的朋友。如若对你有帮助的话请点个赞(不介意的可以投个币)。如若引用还请注明出处!读这篇文章之前,你必须对原码反码补码有所了解。关于这些推荐一篇大佬的文章。[关于原码反码和补码](https://blog.csdn.net/chenchao2017/article/details/79733278)在这里补充一点关于补码的知识:a例如:+5的补码为00101-5的补码为11011如果我想用八位二进制补码表示怎么办?答案是从

  • basler 相机_basler相机型号

    basler 相机_basler相机型号尝试

    2022年10月23日
  • 十八万字《python从零到精通教程》第二版,贴心保姆教你从零变大神,学不会找我「建议收藏」

    文章目录一.pycharm下载安装二.python下载安装三.pycharm上配置python四.配置镜像源让你下载嗖嗖的快4.1pycharm内部配置4.2手动添加镜像源4.3永久配置镜像源五.插件安装(比如汉化?)5.1自动补码神器第一款5.2自动补码神器第二款5.2汉化pycharm5.3其它插件六.美女背景七.自定义脚本开头八、这个前言一定要看九、python入门十、python缩进十一、Python注释1.单行注释2.多行注释十二、Python变量1.变量定义理解2.变量名命名3.分配多个

  • Java程序员,你一定需要了解的六款大数据采集平台

    Java程序员,你一定需要了解的六款大数据采集平台随着大数据越来越被重视,数据采集的挑战变的尤为突出。今天为大家介绍几款数据采集平台: ApacheFlume Fluentd Logstash Chukwa Scribe SplunkForwarder 大数据平台与数据采集任何完整的大数据平台,一般包括以下的几个过程: 数据采集 数据存储 数据处理 …

  • 后台管理系统 – 权限设计

    后台管理系统 – 权限设计一、前言对于前端项目特别是中后台管理系统项目,权限设计是最复杂的点之一。一般来说权限设计需要后端来把关,毕竟相对来说前端是无法保证安全的,前端的代码和数据请求都可以伪造。而前端的权限设计更多是为了用户体验的考虑。前端保证体验,后端保证安全。由于前后端的开发差异和侧重点不同,在权限设计上也不一样。后端更多的是根据功能对象划分不同的权限模块,针对接口相应进行权限判断;而前端更多是针对页面路由进行模块划分,针对页面可访问进行判断。接下来将以后台管理系统为例,分享个人对前端权限设计的见解。(具体内容尽量做

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号