PHP - 类声明可能不是嵌套的 [英] PHP - Class declarations may not be nested

查看:378
本文介绍了PHP - 类声明可能不是嵌套的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个项目在cakephp,当我打电话给供应商使用AES解密字符串,我得到的错误:

 致命错误:类声明不能嵌套在第30行的/var/www/html/myproject/cake/libs/log/file_log.php中

这是我的控制器中的代码:

  App :: import ','aes',array('file'=>'AES / AES.php')); 
$ aes = new AesCtr();
$ decryptpted = $ aes-> decrypt($ encrypted,mykey,128);

这是供应商的一部分(一个单一文件名为AES.php):

  class Aes {
//....Methods
}

class AesCtr extends Aes {

public static function decrypt($ ciphertext,$ password,$ nBits){
//....Method Logic
}

//,其他方法

}

这里的解释: PHP嵌套类工作... ...? b $ b但我没有太多的PHP经验,并不能够通过他们显示的hacky方式解决这个问题。



任何帮助是赞赏。如果需要更多信息,请告诉我。



UPDATE
类Aes和AesCtr(都在文件AES.php中)。

 <?php 
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * /
/ * PHP中的AES实现* /
/ * 2005-2011 www.movable-type.co.uk/scripts * /
/ *所有商业或非商业用途的免费使用权,提供此* /
/ *版权声明保留。不提供任何形式的保证。 * /
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * /

class Aes {

/ **
* AES密码功能:使用Rijndael算法加密'输入'
*
* @param输入消息作为字节数组(16字节)
* @param w密钥计划作为2D字节数组(Nr + 1 x Nb字节) -
* key by keyExpansion()
* @以字节数组(16字节)形式返回密文
* /
public static function cipher($ input,$ w){// main cipher function 5.1]
$ Nb = 4; //块大小(以字为单位):状态列数(固定为4,AES)
$ Nr = count($ w)/ $ Nb - 1; // no of rounds:10/12/14 for 128/192/256-bit keys

$ state = array(); // initialize 4xNb byte-array'state'with input [§3.4]
for($ i = 0; $ i <4 * $ Nb; $ i ++)$ state [$ i%4] i / 4)] = $ input [$ i];

$ state = self :: addRoundKey($ state,$ w,0,$ Nb);

for($ round = 1; $ round< $ Nr; $ round ++){// apply Nr rounds
$ state = self :: subBytes($ state,$ Nb);
$ state = self :: shiftRows($ state,$ Nb);
$ state = self :: mixColumns($ state,$ Nb);
$ state = self :: addRoundKey($ state,$ w,$ round,$ Nb);
}

$ state = self :: subBytes($ state,$ Nb);
$ state = self :: shiftRows($ state,$ Nb);
$ state = self :: addRoundKey($ state,$ w,$ Nr,$ Nb);

$ output = array(4 * $ Nb); //在返回之前将状态转换为1-d数组[§3.4]
for($ i = 0; $ i <4 * $ Nb; $ i ++)$ output [$ i] = $ state [$ i% 4] [floor($ i / 4)];
return $ output;
}


私人静态函数addRoundKey($ state,$ w,$ rnd,$ Nb){//将圆键变成状态S [§5.1.4]
for($ r = 0; $ r <4; $ r ++){
for($ c = 0; $ c <$ Nb; $ c ++)$ state [$ r] [$ c] = $ w [$ rnd * 4 + $ c] [$ r];
}
return $ state;
}

私人静态函数subBytes($ s,$ Nb){//将SBox应用于状态S [§5.1.1]
for($ r = 0; $ r <4; $ r ++){
for($ c = 0; $ c <$ Nb; $ c ++)$ s [$ r] [$ c] = self :: $ sBox [$ s [$ r ] [$ c]];
}
return $ s;
}

私有静态函数shiftRows($ s,$ Nb){//将状态S的行r移位r个字节[§5.1.2]
$ t =数组(4);
for($ r = 1; $ r< 4; $ r ++){
for($ c = 0; $ c <4; $ c ++)$ t [$ c] = $ s [$ r] [($ c + $ r)%$ Nb]; // shift into temp copy
for($ c = 0; $ c< 4; $ c ++)$ s [$ r] [$ c] = $ t [$ c] //并复制回
} //注意这将适用于Nb = 4,5,6,但不是7,8(对于AES总是为4):
return $ s; // see fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.311.pdf
}

私有静态函数mixColumns($ s,$ Nb){// combine ($ c = 0; $ c <4; $ c ++){
$ a = array(4);每个字节的状态S [§5.1.3]
//'a'是's'的当前列的副本
$ b = array(4); //'b'is a {02} in GF(2 ^ 8)
for($ i = 0; $ i <4; $ i ++){
$ a [$ i] = $ s [$ i] [$ c];
$ b [$ i] = $ s [$ i] [$ c]& 0x80? $ s [$ i] [$ c]<< 1 ^ 0x011b:$ s [$ i] [$ c] <&
}
// a [n] ^ b [n]是GF(2 ^ 8)中的{03}
$ s [0] [$ c] = $ b [ 0] ^ $ a [1] ^ $ b [1] ^ $ a [2] ^ $ a [3]; // 2 * a0 + 3 * a1 + a2 + a3
$ s [1] [$ c] = $ a [0] ^ $ b [1] ^ $ a [2] ^ $ a [3]; // a0 * 2 * a1 + 3 * a2 + a3
$ s [2] [$ c] = $ a [0] ^ $ a [1] ^ $ b [2] ^ $ a [3] ^ $ b [3]; // a0 + a1 + 2 * a2 + 3 * a3
$ s [3] [$ c] = $ a [0] ^ $ b [0] ^ $ a [1] ^ $ a [2] ^ $ b [3]; // 3 * a0 + a1 + a2 + 2 * a3
}
return $ s;
}

/ **
* Rijndael的密钥扩展cipher():对密钥key执行密钥扩展
*以生成密钥计划
*
* @param密钥密钥字节数组(16字节)
* @将键调度作为2D字节数组(Nr + 1 x Nb字节)返回
* /
public静态函数keyExpansion($ key){//从密钥生成密钥计划[§5.2]
$ Nb = 4; //块大小(以字为单位):状态列数(对于AES固定为4)
$ Nk = count($ key)/ 4; //密钥长度(字):4/6/8对于128/192/256位密钥
$ Nr = $ Nk + 6; // no of rounds:10/12/14 for 128/192/256-bit keys

$ w = array();
$ temp = array();

for($ i = 0; $ i <$ Nk; $ i ++){
$ r = array($ key [4 * $ i],$ key [4 * $ i +1],$ key [4 * $ i + 2],$ key [4 * $ i + 3]);
$ w [$ i] = $ r;
}

for($ i = $ Nk; $ i<($ Nb *($ Nr + 1)); $ i ++){
$ w [$ i] = array();
for($ t = 0; $ t< 4; $ t ++)$ temp [$ t] = $ w [$ i-1] [$ t]
if($ i%$ Nk == 0){
$ temp = self :: subWord(self :: rotWord($ temp));
for($ t = 0; $ t <4; $ t ++)$ temp [$ t] ^ = self :: $ rCon [$ i / $ Nk] [$ t];
} else if($ Nk> 6&& $ i%$ Nk == 4){
$ temp = self :: subWord($ temp);
}
for($ t = 0; $ t <4; $ t ++)$ w [$ i] [$ t] = $ w [$ i- $ Nk] [$ t] ^ $ temp [$ t];
}
return $ w;
}

私有静态函数subWord($ w){//将SBox应用于4字节字w
for($ i = 0; $ i <4; $ i ++ )$ w [$ i] = self :: $ sBox [$ w [$ i]];
return $ w;
}

私人静态函数rotWord($ w){//将一个字节左移四个字节的字w
$ tmp = $ w [0];
for($ i = 0; $ i< 3; $ i ++)$ w [$ i] = $ w [$ i + 1];
$ w [3] = $ tmp;
return $ w;
}

// sBox是在subBytes和keyExpansion中使用的GF(2 ^ 8)中预先计算的乘法逆矩阵
private static $ sBox = array (
0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,
0xca,0x82,0xc9,0x7d,0xfa ,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,
0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1 ,0x71,0xd8,0x31,0x15,
0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,
0x09 ,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,
0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b ,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,
0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f ,0xa8,
0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,
0xcd,0x0c,0x13,0xec ,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,
0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8 ,0x14,0xde,0x5e,0x0b,0xdb,
0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,
0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,
0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4 ,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,
0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1 ,0x1d,0x9e,
0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55​​,0x28,0xdf,
0x8c,0xa1,0x89 ,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16);

// rCon是用于密钥扩展的round常数[第1列是GF(2 ^ 8)中的2 ^(r-1)] [§5.2]
private static $ rCon = array(
array(0x00,0x00,0x00,0x00),
array(0x01,0x00,0x00,0x00),
array(0x02,0x00,0x00,0x00),
数组(0x04,0x00,0x00,0x00),
数组(0x08,0x00,0x00,0x00),
数组(0x10,0x00,0x00,0x00),
数组,0x00,0x00,0x00),
数组(0x40,0x00,0x00,0x00),
数组(0x80,0x00,0x00,0x00),
数组(0x1b,0x00,0x00, 0x00),
array(0x36,0x00,0x00,0x00));

}

/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * /
?>

<?php
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * /
/ * PHP计数器(CTR)模式实现* /
/ *(c)Chris Veness 2005-2011 www。 movable-type.co.uk/scripts * /
/ *保留所有商业或非商业用途的免费使用权,提供此* /
/ *版权声明。不提供任何形式的保证。 * /
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * /

类AesCtr扩展Aes {

/ **
*在计数器操作模式下使用AES加密加密文本
* - 请参阅http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
*
* Unicode多字节字符安全
*
* @param要加密的明文源文本
* @param密码用于生成密钥的密码
* @param nBits要在密钥中使用的位数(128,192或256)
* @return加密文本
* /
public static function encrypt($ plaintext,$ password,$ nBits){
$ blockSize = 16; //块大小固定为16字节/ 128位(Nb = 4)对于AES
if(!nBits == 128 || $ nBits == 192 || $ nBits == 256) ; //标准允许128/192/256位密钥
//注意PHP(5)给出了UTF8编码中的纯文本和密码!

//使用AES本身来加密密码以获得密码密钥(使用纯密码作为
的密钥扩展) - 给我们很好的加密密钥
$ nBytes = $ nBits / 8; //密钥中没有字节
$ pwBytes = array();
for($ i = 0; $ i <$ nBytes; $ i ++)$ pwBytes [$ i] = ord(substr($ password,$ i,1))& 0xff;
$ key = Aes :: cipher($ pwBytes,Aes :: keyExpansion($ pwBytes));
$ key = array_merge($ key,array_slice($ key,0,$ nBytes-16)); //展开键到16/24/32字节长

//用nonce初始化计数器块的第一个8字节(NIST SP800-38A§B.2):[0-1] =毫秒,
// [2-3] = random,[4-7] = seconds,给出保证的sub-ms唯一性直到2月2106
$ counterBlock = array();
$ nonce = floor(microtime(true)* 1000); // timestamp:从1970年1月1日起的毫秒
$ nonceMs = $ nonce%1000;
$ nonceSec = floor($ nonce / 1000);
$ nonceRnd = floor(rand(0,0xffff));

for($ i = 0; $ i <2; $ i ++)$ counterBlock [$ i] = self :: urs($ nonceMs,$ i * 8)& 0xff;
for($ i = 0; $ i <2; $ i ++)$ counterBlock [$ i + 2] = self :: urs($ nonceRnd,$ i * 8)& 0xff;
for($ i = 0; $ i <4; $ i ++)$ counterBlock [$ i + 4] = self :: urs($ nonceSec,$ i * 8)& 0xff;

//并将其转换为一个字符串,位于密文前面
$ ctrTxt ='';
for($ i = 0; $ i <8; $ i ++)$ ctrTxt。= chr($ counterBlock [$ i]);

//生成密钥调度 - 每个循环将键扩展为不同的密钥轮次
$ keySchedule = Aes :: keyExpansion($ key);
// print_r($ keySchedule);

$ blockCount = ceil(strlen($ plaintext)/ $ blockSize);
$ ciphertxt = array(); //密文作为字符串数组

for($ b = 0; $ b <$ blockCount; $ b ++){
//在计数器的最后8个字节中设置计数器块(在1个8字节中留下nonce)
//对于32位操作,以两个阶段完成:使用两个字使我们可以经过2 ^ 32个块(68GB)
($ c = 0 ; $ c< 4; $ c ++)$ counterBlock [15- $ c] = self :: urs($ b,$ c * 8)& 0xff;
for($ c = 0; $ c <4; $ c ++)$ counterBlock [15- $ c-4] = self :: urs($ b / 0x100000000,$ c * 8)

$ cipherCntr = Aes :: cipher($ counterBlock,$ keySchedule); // - 加密计数器块 -

//最终块上的块大小减少
$ blockLength = $ b <$ blockCount-1? $ blockSize:(strlen($ plaintext)-1)%$ blockSize + 1;
$ cipherByte = array();

for($ i = 0; $ i <$ blockLength; $ i ++){// - 带有加密计数器的纯文本逐字节 -
$ cipherByte [$ i ] = $ cipherCntr [$ i] ^ ord(substr($ plaintext,$ b * $ blockSize + $ i,1));
$ cipherByte [$ i] = chr($ cipherByte [$ i]);
}
$ cryptotxt [$ b] = implode('',$ cipherByte); // escape密文中的字符
}

// implode比重复字符串连接更有效
$ ciphertext = $ ctrTxt。 implode('',$ ciphertxt);
$ ciphertext = base64_encode($ ciphertext);
return $ ciphertext;
}


/ **
*以计数器操作模式解密AES加密的文本
*
* @param密文源要解密的文本
* @param password用于生成密钥的密码
* @param nBits要在密钥(128,192或256)中使用的位数
* @返回解密的文本
* /
public static function decrypt($ ciphertext,$ password,$ nBits){
$ blockSize = 16; //块大小固定为16字节/ 128位(Nb = 4)对于AES
if(!nBits == 128 || $ nBits == 192 || $ nBits == 256) ; // standard允许128/192/256位密钥
// $ ciphertext = AesCtr :: hexToStr($ ciphertext);
$ ciphertext = base64_decode($ ciphertext);


//使用AES加密密码(镜像加密例程)
$ nBytes = $ nBits / 8; //密钥中没有字节
$ pwBytes = array();
for($ i = 0; $ i <$ nBytes; $ i ++)$ pwBytes [$ i] = ord(substr($ password,$ i,1))& 0xff;
$ key = Aes :: cipher($ pwBytes,Aes :: keyExpansion($ pwBytes));
$ key = array_merge($ key,array_slice($ key,0,$ nBytes-16)); // expand key to 16/24/32 bytes long

//从密文的第一个元素恢复nonce
$ counterBlock = array();
$ ctrTxt = substr($ ciphertext,0,8);
for($ i = 0; $ i <8; $ i ++)$ counterBlock [$ i] = ord(substr($ ctrTxt,$ i,1));

//生成密钥计划
$ keySchedule = Aes :: keyExpansion($ key);

//将密文分割成块(跳过最初的8个字节)
$ nBlocks = ceil((strlen($ ciphertext)-8)/ $ blockSize);
$ ct = array();
for($ b = 0; $ b <$ nBlocks; $ b ++)$ ct [$ b] = substr($ ciphertext,8 + $ b * $ blockSize,16)
$ ciphertext = $ ct; //密文现在是块长度字符串数组

//纯文本将逐块生成到块长度字符串数组
$ plaintxt = array();

for($ b = 0; $ b< $ nBlocks; $ b ++){
//在计数器块的最后8个字节中设置计数器字节)
for($ c = 0; $ c <4; $ c ++)$ counterBlock [15- $ c] = self :: urs($ b,$ c * 8)& 0xff;
for($ c = 0; $ c <4; $ c ++)$ counterBlock [15- $ c-4] = self :: urs(($ b + 1)/ 0x100000000-1,$ c * 8 )& 0xff;

$ cipherCntr = Aes :: cipher($ counterBlock,$ keySchedule); //加密计数器块

$ plaintxtByte = array();
for($ i = 0; $ i // - 带有加密计数器的纯文本逐字节 -
$ plaintxtByte [$ i] = $ cipherCntr [$ i] ^ ord(substr($ ciphertext [$ b],$ i,1));
$ plaintxtByte [$ i] = chr($ plaintxtByte [$ i]);

}
$ plaintxt [$ b] = implode('',$ plaintxtByte);
}

//将块数组合并为单个纯文本字符串
$ plaintext = implode('',$ plaintxt);

return $ plaintext;
}

/ *解码十六进制* /
public static function hexToStr($ hex)
{
$ string ='';
for($ i = 0; $ i< strlen($ hex)-1; $ i + = 2)
{
$ string。= chr(hexdec($ hex [$ i ]。$ hex [$ i + 1]));
}
return $ string;
}


/ *
*无符号右移函数,因为PHP既不具有>>>运算符也不是无符号整数
*
* @param要移位的数字(32位整数)
* @param b向右移位的位数(0..31)
* @返回一个右移和零填充b位
* /
私人静态函数urs($ a,$ b){
$ a& = 0xffffffff ; $ b& = 0x1f; //(bounds check)
if($ a& 0x80000000&& $ b> 0){//如果最左边的位设置
$ a =($ a>> 1)& ; 0x7fffffff; //右移一位&清除最左边的位
$ a = $ a>> ($ b-1); //剩下的右移
} else {//否则
$ a =($ a>> $ b); // use normal right-shift
}
return $ a;
}

}
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * /
?>对不起,我应该提到这个,这段代码在我的电脑上工作得很好,我得到那个错误,当我上传项目到服务器,完整的消息是:


注意(8):十六进制数字太大:0x100000000
[core / vendors / AES / AES.php,line 230]



致命错误:类声明不能嵌套在
/ var / www / html /myproject/cake/libs/log/file_log.php on line 30


所以我不知道错误是在



UPDATE 2:file_log.php,发生致命错误(这里是一个文件描述

 <?php 
/ **
*文件存储流记录
*
* PHP版本4和5
*
* CakePHP tm):快速开发框架(http://cakephp.org)
*版权所有2005-2010,Cake Software Foundation,Inc.(http://cakefoundation.org)
*
*根据MIT许可证授权
*文件的再分发必须保留上述版权声明。
*
* @copyright版权所有2005-2010,Cake Software Foundation,Inc.(http://cakefoundation.org)
* @link http://www.cakefoundation.org/projects / info / cakephp CakePHP(tm)Project
* @package cake
* @subpackage cake.cake.libs.log
* @since CakePHP(tm)v 1.3
* @许可证MIT许可证(http://www.opensource.org/licenses/mit-license.php)
* /
if(!class_exists('File')){
require LIBS。 'file.php';
}
/ **
*用于日志记录的文件存储流。根据日志类型将日志写入不同的文件
*。
*
* @package cake
* @subpackage cake.cake.libs.log
* /
class FileLog {

/ * *
*保存日志文件的路径。
*
* @var string
* /
var $ _path = null;

/ **
*构造一个新的文件记录器。
*
*选项
*
* - `path`保存日志的路径。
*
* @param array $ options FileLog的选项,见上文。
* @return void
* /
function FileLog($ options = array()){
$ options + = array('path'=> LOGS)
$ this-> _path = $ options ['path'];
}

/ **
*实现写入日志文件。
*
* @param string $ type您正在进行的日志类型。
* @param string $ message您要记录的消息。
* @return boolean write of write。
* /
function write($ type,$ message){
$ debugTypes = array('notice','info','debug');

if($ type =='error'|| $ type =='warning'){
$ filename = $ this-> _path。 'error.log';
} elseif(in_array($ type,$ debugTypes)){
$ filename = $ this-> _path。 'debug.log';
} else {
$ filename = $ this-> _path。 $ type。 '.log';
}
$ output = date('Y-m-d H:i:s')。 ''。 ucfirst($ type)。 ':'。 $ message。 \\\
;
$ log = new File($ filename,true);
if($ log-> writable()){
return $ log-> append($ output);
}
}
}


解决方案

好吧,这次我更好地集中,这里有一个可能的问题/解决方案:



你也可以发布这个文件: / var / www / html / myproject / cake / libs / log / file_log.php ,因为它似乎错误发生在这里,而不是AES.php:



致命错误:类声明不能嵌套在第30行的/var/www/html/myproject/cake/libs/log/file_log.php中



我认为注意致命错误是两个不同的事情,不应该混在一起。
有一个关于太大整数值(转换为float)和其他关于嵌套类彼此的致命错误的通知。



如何Aes和AesCtr应该使用:



Aes和AesCtr都是完全静态的类,所以没有必要实例化它们:



更改:

  $ aes = new AesCtr 
$ decryptpted = $ aes-> decrypt($ encrypted,mykey,128);

To:

  $ decryptpted = AesCtr :: decrypt($ encrypted,mykey,128); 

是的,您应该删除 $ aes = new AesCtr



这是关于通知,AES.php第230行:



在AES.php的第230行,有一个十六进制数字 0x100000000 ,它不是有效的有符号32位整数(实际上,它至少需要33位如果未签名),一些PHP版本将抛出一个错误或通知(更旧的主要)。我使用PHP 5.3,即使使用 error_reporting(E_ALL);



签名的整数最大值是 2147483647 或以十六进制 0x7FFFFFFF 和AES.php尝试
使用



language.types.integer.php 说: PHP中没有整数除法运算符。

我认为问题是,如错误信息中所述,十六进制数太大: 0x100000000 ,php尝试使用该十六进制值作为整数,但它太大,所以它首先转换为float。





  var_dump(0x100000000); 
var_dump((int)0x100000000);

在32位系统中输出:

  float(4294967296)
int(0)

与64位系统相同:

  int(4294967296)
int(4294967296)



如何解决?



这里的解决方案可能会或可能不工作:



只需使用 4294967296.0 替换 0x100000000 将如下所示:

  for($ c = 0; $ c <4; $ c ++)$ counterBlock [15- $ c-4] = self :: urs($ b / 4294967296.0,$ c * 8); 

也许你还应该检查 urs()尝试做,以及它如何尝试这样做。但是,它应该已经预期浮点值作为参数,请参见整数



更新:



检查urs()似乎期望int作为第一个arg,从(x / y)操作,如果有分数则返回float,否则返回int。



使它再次int是简单的类型转换使用(int)(x / y),没有缺点(或很少)相比旧的方式,这只是转换



最初,在修改之前,转换为浮动的可能性和可行性与现在 urs() doc说第一个arg应该是int)

  for($ c = 0; $ c <4; $ c ++)$ counterBlock [15- $ c -4] = self :: urs((int)($ b / 4294967296.0),$ c * 8); 



更新:file_log.php



认为 file_log.php 没有什么问题,它声明了类FileLog ,它正确实现并关闭到我可以看到。



file_log.php 的其他事情是,它似乎是cakephp的内部库和加载通过cakephp框架。我不知道任何关于cakephp ...



但是,你真的应该测试你的代码没有 AES.php 或者可以尝试包括 AES.php 一些其他方式像这样测试 App :: import()无法正常工作

  / *记住考虑到文件名推荐
*在服务器区分大小写,但也许不区分大小写在
*你的工作站(如果在windows下开发)。 * /

//如果需要,将vendor / AES / AES.php更改为正确的路径:
require_once'vendors / AES / AES.php';
$ decryptpted = AesCtr :: decrypt($ encrypted,mykey,128);

或可能(来自cakephp手册):



  //供应商不是供应商和AES / AES不是aes / AES或aes / aes只是为了确保... 
App :: import('Vendor','AES / AES');
$ decryptpted = AesCtr :: decrypt($ encrypted,mykey,128);

或者完全退出:

  $ decryptpted ='dummytest'; 

或者可以包含而不使用它:

  App :: import('vendor','aes',array('file'=>'AES / AES.php ')); 
$ decryptpted ='dummytest';

而不是:

  App :: import('vendor','aes',array('file'=>'AES / AES.php')); 
$ decryptpted = AesCtr :: decrypt($ encrypted,mykey,128);

这种方式的问题被缩小,如果同样的错误仍然弹出然后
问题是在别的地方,但如果错误消失后,测试,那么我们知道错误是在App :: import()或在cakephp框架中的某处。


I have a project in cakephp, when I call a vendor for decrypting a string using AES, I get the error:

Fatal error: Class declarations may not be nested in /var/www/html/myproject/cake/libs/log/file_log.php on line 30

This is the code in my controller:

App::import('vendor', 'aes', array('file' => 'AES/AES.php'));
$aes = new AesCtr();
$decrypted = $aes->decrypt($encrypted, "mykey", 128);

And this is part of the vendor (one single file called AES.php):

class Aes {
//....Methods
}

class AesCtr extends Aes {

  public static function decrypt($ciphertext, $password, $nBits) {
  //....Method Logic
  }

  //....Other methods

}

I've read the explanation given here: PHP Nested classes work... sort of? but I have no much experience in PHP and wasn't able to solve this issue by the "hacky way" that they showed.

Any help is appreciated. If more info is needed, please tell me.

UPDATE Classes Aes and AesCtr (both are in file AES.php).

<?php
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
/*  AES implementation in PHP                                                                     */
/*    (c) Chris Veness 2005-2011 www.movable-type.co.uk/scripts                                   */
/*    Right of free use is granted for all commercial or non-commercial use providing this        */
/*    copyright notice is retainded. No warranty of any form is offered.                          */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */

class Aes {

  /**
   * AES Cipher function: encrypt 'input' with Rijndael algorithm
   *
   * @param input message as byte-array (16 bytes)
   * @param w     key schedule as 2D byte-array (Nr+1 x Nb bytes) - 
   *              generated from the cipher key by keyExpansion()
   * @return      ciphertext as byte-array (16 bytes)
   */
  public static function cipher($input, $w) {    // main cipher function [§5.1]
    $Nb = 4;                 // block size (in words): no of columns in state (fixed at 4 for AES)
    $Nr = count($w)/$Nb - 1; // no of rounds: 10/12/14 for 128/192/256-bit keys

    $state = array();  // initialise 4xNb byte-array 'state' with input [§3.4]
    for ($i=0; $i<4*$Nb; $i++) $state[$i%4][floor($i/4)] = $input[$i];

    $state = self::addRoundKey($state, $w, 0, $Nb);

    for ($round=1; $round<$Nr; $round++) {  // apply Nr rounds
      $state = self::subBytes($state, $Nb);
      $state = self::shiftRows($state, $Nb);
      $state = self::mixColumns($state, $Nb);
      $state = self::addRoundKey($state, $w, $round, $Nb);
    }

    $state = self::subBytes($state, $Nb);
    $state = self::shiftRows($state, $Nb);
    $state = self::addRoundKey($state, $w, $Nr, $Nb);

    $output = array(4*$Nb);  // convert state to 1-d array before returning [§3.4]
    for ($i=0; $i<4*$Nb; $i++) $output[$i] = $state[$i%4][floor($i/4)];
    return $output;
  }


  private static function addRoundKey($state, $w, $rnd, $Nb) {  // xor Round Key into state S [§5.1.4]
    for ($r=0; $r<4; $r++) {
      for ($c=0; $c<$Nb; $c++) $state[$r][$c] ^= $w[$rnd*4+$c][$r];
    }
    return $state;
  }

  private static function subBytes($s, $Nb) {    // apply SBox to state S [§5.1.1]
    for ($r=0; $r<4; $r++) {
      for ($c=0; $c<$Nb; $c++) $s[$r][$c] = self::$sBox[$s[$r][$c]];
    }
    return $s;
  }

  private static function shiftRows($s, $Nb) {    // shift row r of state S left by r bytes [§5.1.2]
    $t = array(4);
    for ($r=1; $r<4; $r++) {
      for ($c=0; $c<4; $c++) $t[$c] = $s[$r][($c+$r)%$Nb];  // shift into temp copy
      for ($c=0; $c<4; $c++) $s[$r][$c] = $t[$c];           // and copy back
    }          // note that this will work for Nb=4,5,6, but not 7,8 (always 4 for AES):
    return $s;  // see fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.311.pdf 
  }

  private static function mixColumns($s, $Nb) {   // combine bytes of each col of state S [§5.1.3]
    for ($c=0; $c<4; $c++) {
      $a = array(4);  // 'a' is a copy of the current column from 's'
      $b = array(4);  // 'b' is a•{02} in GF(2^8)
      for ($i=0; $i<4; $i++) {
        $a[$i] = $s[$i][$c];
        $b[$i] = $s[$i][$c]&0x80 ? $s[$i][$c]<<1 ^ 0x011b : $s[$i][$c]<<1;
      }
      // a[n] ^ b[n] is a•{03} in GF(2^8)
      $s[0][$c] = $b[0] ^ $a[1] ^ $b[1] ^ $a[2] ^ $a[3]; // 2*a0 + 3*a1 + a2 + a3
      $s[1][$c] = $a[0] ^ $b[1] ^ $a[2] ^ $b[2] ^ $a[3]; // a0 * 2*a1 + 3*a2 + a3
      $s[2][$c] = $a[0] ^ $a[1] ^ $b[2] ^ $a[3] ^ $b[3]; // a0 + a1 + 2*a2 + 3*a3
      $s[3][$c] = $a[0] ^ $b[0] ^ $a[1] ^ $a[2] ^ $b[3]; // 3*a0 + a1 + a2 + 2*a3
    }
    return $s;
  }

  /**
   * Key expansion for Rijndael cipher(): performs key expansion on cipher key
   * to generate a key schedule
   *
   * @param key cipher key byte-array (16 bytes)
   * @return    key schedule as 2D byte-array (Nr+1 x Nb bytes)
   */
  public static function keyExpansion($key) {  // generate Key Schedule from Cipher Key [§5.2]
    $Nb = 4;              // block size (in words): no of columns in state (fixed at 4 for AES)
    $Nk = count($key)/4;  // key length (in words): 4/6/8 for 128/192/256-bit keys
    $Nr = $Nk + 6;        // no of rounds: 10/12/14 for 128/192/256-bit keys

    $w = array();
    $temp = array();

    for ($i=0; $i<$Nk; $i++) {
      $r = array($key[4*$i], $key[4*$i+1], $key[4*$i+2], $key[4*$i+3]);
      $w[$i] = $r;
    }

    for ($i=$Nk; $i<($Nb*($Nr+1)); $i++) {
      $w[$i] = array();
      for ($t=0; $t<4; $t++) $temp[$t] = $w[$i-1][$t];
      if ($i % $Nk == 0) {
        $temp = self::subWord(self::rotWord($temp));
        for ($t=0; $t<4; $t++) $temp[$t] ^= self::$rCon[$i/$Nk][$t];
      } else if ($Nk > 6 && $i%$Nk == 4) {
        $temp = self::subWord($temp);
      }
      for ($t=0; $t<4; $t++) $w[$i][$t] = $w[$i-$Nk][$t] ^ $temp[$t];
    }
    return $w;
  }

  private static function subWord($w) {    // apply SBox to 4-byte word w
    for ($i=0; $i<4; $i++) $w[$i] = self::$sBox[$w[$i]];
    return $w;
  }

  private static function rotWord($w) {    // rotate 4-byte word w left by one byte
    $tmp = $w[0];
    for ($i=0; $i<3; $i++) $w[$i] = $w[$i+1];
    $w[3] = $tmp;
    return $w;
  }

  // sBox is pre-computed multiplicative inverse in GF(2^8) used in subBytes and keyExpansion [§5.1.1]
  private static $sBox = array(
    0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,
    0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,
    0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,
    0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,
    0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,
    0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,
    0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,
    0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,
    0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,
    0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,
    0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,
    0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,
    0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,
    0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,
    0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,
    0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16);

  // rCon is Round Constant used for the Key Expansion [1st col is 2^(r-1) in GF(2^8)] [§5.2]
  private static $rCon = array( 
    array(0x00, 0x00, 0x00, 0x00),
    array(0x01, 0x00, 0x00, 0x00),
    array(0x02, 0x00, 0x00, 0x00),
    array(0x04, 0x00, 0x00, 0x00),
    array(0x08, 0x00, 0x00, 0x00),
    array(0x10, 0x00, 0x00, 0x00),
    array(0x20, 0x00, 0x00, 0x00),
    array(0x40, 0x00, 0x00, 0x00),
    array(0x80, 0x00, 0x00, 0x00),
    array(0x1b, 0x00, 0x00, 0x00),
    array(0x36, 0x00, 0x00, 0x00) ); 

} 

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
?>

<?php
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
/*  AES counter (CTR) mode implementation in PHP                                                  */
/*    (c) Chris Veness 2005-2011 www.movable-type.co.uk/scripts                                   */
/*    Right of free use is granted for all commercial or non-commercial use providing this        */
/*    copyright notice is retainded. No warranty of any form is offered.                          */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */

class AesCtr extends Aes {

  /** 
   * Encrypt a text using AES encryption in Counter mode of operation
   *  - see http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
   *
   * Unicode multi-byte character safe
   *
   * @param plaintext source text to be encrypted
   * @param password  the password to use to generate a key
   * @param nBits     number of bits to be used in the key (128, 192, or 256)
   * @return          encrypted text
   */
  public static function encrypt($plaintext, $password, $nBits) {
    $blockSize = 16;  // block size fixed at 16 bytes / 128 bits (Nb=4) for AES
    if (!($nBits==128 || $nBits==192 || $nBits==256)) return '';  // standard allows 128/192/256 bit keys
    // note PHP (5) gives us plaintext and password in UTF8 encoding!

    // use AES itself to encrypt password to get cipher key (using plain password as source for  
    // key expansion) - gives us well encrypted key
    $nBytes = $nBits/8;  // no bytes in key
    $pwBytes = array();
    for ($i=0; $i<$nBytes; $i++) $pwBytes[$i] = ord(substr($password,$i,1)) & 0xff;
    $key = Aes::cipher($pwBytes, Aes::keyExpansion($pwBytes));
    $key = array_merge($key, array_slice($key, 0, $nBytes-16));  // expand key to 16/24/32 bytes long 

    // initialise 1st 8 bytes of counter block with nonce (NIST SP800-38A §B.2): [0-1] = millisec, 
    // [2-3] = random, [4-7] = seconds, giving guaranteed sub-ms uniqueness up to Feb 2106
    $counterBlock = array();
    $nonce = floor(microtime(true)*1000);   // timestamp: milliseconds since 1-Jan-1970
    $nonceMs = $nonce%1000;
    $nonceSec = floor($nonce/1000);
    $nonceRnd = floor(rand(0, 0xffff));

    for ($i=0; $i<2; $i++) $counterBlock[$i]   = self::urs($nonceMs,  $i*8) & 0xff;
    for ($i=0; $i<2; $i++) $counterBlock[$i+2] = self::urs($nonceRnd, $i*8) & 0xff;
    for ($i=0; $i<4; $i++) $counterBlock[$i+4] = self::urs($nonceSec, $i*8) & 0xff;

    // and convert it to a string to go on the front of the ciphertext
    $ctrTxt = '';
    for ($i=0; $i<8; $i++) $ctrTxt .= chr($counterBlock[$i]);

    // generate key schedule - an expansion of the key into distinct Key Rounds for each round
    $keySchedule = Aes::keyExpansion($key);
    //print_r($keySchedule);

    $blockCount = ceil(strlen($plaintext)/$blockSize);
    $ciphertxt = array();  // ciphertext as array of strings

    for ($b=0; $b<$blockCount; $b++) {
      // set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)
      // done in two stages for 32-bit ops: using two words allows us to go past 2^32 blocks (68GB)
      for ($c=0; $c<4; $c++) $counterBlock[15-$c] = self::urs($b, $c*8) & 0xff;
      for ($c=0; $c<4; $c++) $counterBlock[15-$c-4] = self::urs($b/0x100000000, $c*8);

      $cipherCntr = Aes::cipher($counterBlock, $keySchedule);  // -- encrypt counter block --

      // block size is reduced on final block
      $blockLength = $b<$blockCount-1 ? $blockSize : (strlen($plaintext)-1)%$blockSize+1;
      $cipherByte = array();

      for ($i=0; $i<$blockLength; $i++) {  // -- xor plaintext with ciphered counter byte-by-byte --
        $cipherByte[$i] = $cipherCntr[$i] ^ ord(substr($plaintext, $b*$blockSize+$i, 1));
        $cipherByte[$i] = chr($cipherByte[$i]);
      }
      $ciphertxt[$b] = implode('', $cipherByte);  // escape troublesome characters in ciphertext
    }

    // implode is more efficient than repeated string concatenation
    $ciphertext = $ctrTxt . implode('', $ciphertxt);
    $ciphertext = base64_encode($ciphertext);
    return $ciphertext;
  }


  /** 
   * Decrypt a text encrypted by AES in counter mode of operation
   *
   * @param ciphertext source text to be decrypted
   * @param password   the password to use to generate a key
   * @param nBits      number of bits to be used in the key (128, 192, or 256)
   * @return           decrypted text
   */
  public static function decrypt($ciphertext, $password, $nBits) {
    $blockSize = 16;  // block size fixed at 16 bytes / 128 bits (Nb=4) for AES
    if (!($nBits==128 || $nBits==192 || $nBits==256)) return '';  // standard allows 128/192/256 bit keys
    //$ciphertext = AesCtr::hexToStr($ciphertext);
    $ciphertext = base64_decode($ciphertext);


    // use AES to encrypt password (mirroring encrypt routine)
    $nBytes = $nBits/8;  // no bytes in key
    $pwBytes = array();
    for ($i=0; $i<$nBytes; $i++) $pwBytes[$i] = ord(substr($password,$i,1)) & 0xff;
    $key = Aes::cipher($pwBytes, Aes::keyExpansion($pwBytes));
    $key = array_merge($key, array_slice($key, 0, $nBytes-16));  // expand key to 16/24/32 bytes long

    // recover nonce from 1st element of ciphertext
    $counterBlock = array();
    $ctrTxt = substr($ciphertext, 0, 8);
    for ($i=0; $i<8; $i++) $counterBlock[$i] = ord(substr($ctrTxt,$i,1));

    // generate key schedule
    $keySchedule = Aes::keyExpansion($key);

    // separate ciphertext into blocks (skipping past initial 8 bytes)
    $nBlocks = ceil((strlen($ciphertext)-8) / $blockSize);
    $ct = array();
    for ($b=0; $b<$nBlocks; $b++) $ct[$b] = substr($ciphertext, 8+$b*$blockSize, 16);
    $ciphertext = $ct;  // ciphertext is now array of block-length strings

    // plaintext will get generated block-by-block into array of block-length strings
    $plaintxt = array();

    for ($b=0; $b<$nBlocks; $b++) {
      // set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)
      for ($c=0; $c<4; $c++) $counterBlock[15-$c] = self::urs($b, $c*8) & 0xff;
      for ($c=0; $c<4; $c++) $counterBlock[15-$c-4] = self::urs(($b+1)/0x100000000-1, $c*8) & 0xff;

      $cipherCntr = Aes::cipher($counterBlock, $keySchedule);  // encrypt counter block

      $plaintxtByte = array();
      for ($i=0; $i<strlen($ciphertext[$b]); $i++) {
        // -- xor plaintext with ciphered counter byte-by-byte --
        $plaintxtByte[$i] = $cipherCntr[$i] ^ ord(substr($ciphertext[$b],$i,1));
        $plaintxtByte[$i] = chr($plaintxtByte[$i]);

      }
      $plaintxt[$b] = implode('', $plaintxtByte); 
    }

    // join array of blocks into single plaintext string
    $plaintext = implode('',$plaintxt);

    return $plaintext;
  }

  /* Decode Hexadecimal */
  public static function hexToStr($hex)
  {
    $string='';
    for ($i=0; $i < strlen($hex)-1; $i+=2)
    {
        $string .= chr(hexdec($hex[$i].$hex[$i+1]));
    }
    return $string;
  }


  /*
   * Unsigned right shift function, since PHP has neither >>> operator nor unsigned ints
   *
   * @param a  number to be shifted (32-bit integer)
   * @param b  number of bits to shift a to the right (0..31)
   * @return   a right-shifted and zero-filled by b bits
   */
  private static function urs($a, $b) {
    $a &= 0xffffffff; $b &= 0x1f;  // (bounds check)
    if ($a&0x80000000 && $b>0) {   // if left-most bit set
      $a = ($a>>1) & 0x7fffffff;   //   right-shift one bit & clear left-most bit
      $a = $a >> ($b-1);           //   remaining right-shifts
    } else {                       // otherwise
      $a = ($a>>$b);               //   use normal right-shift
    } 
    return $a; 
  }

}  
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
?>

Sorry I should have mentioned this, this code works well on my computer, I get that error when I upload the project to a server, and the complete message is:

Notice (8): Hex number is too big: 0x100000000 [CORE/vendors/AES/AES.php, line 230]

Fatal error: Class declarations may not be nested in /var/www/html/myproject/cake/libs/log/file_log.php on line 30

So I don't know if the error is in the code above or not.

UPDATE 2: file_log.php, where the fatal error occurs (here is a description of the file)

<?php
/**
 * File Storage stream for Logging
 *
 * PHP versions 4 and 5
 *
 * CakePHP(tm) :  Rapid Development Framework (http://cakephp.org)
 * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright     Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
 * @link          http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
 * @package       cake
 * @subpackage    cake.cake.libs.log
 * @since         CakePHP(tm) v 1.3
 * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
 */
if (!class_exists('File')) {
    require LIBS . 'file.php';
}
/**
 * File Storage stream for Logging.  Writes logs to different files
 * based on the type of log it is.
 *
 * @package cake
 * @subpackage cake.cake.libs.log
 */
class FileLog {

/**
 * Path to save log files on.
 *
 * @var string
 */
    var $_path = null;

/**
 * Constructs a new File Logger.
 * 
 * Options
 *
 * - `path` the path to save logs on.
 *
 * @param array $options Options for the FileLog, see above.
 * @return void
 */
    function FileLog($options = array()) {
        $options += array('path' => LOGS);
        $this->_path = $options['path'];
    }

/**
 * Implements writing to log files.
 *
 * @param string $type The type of log you are making.
 * @param string $message The message you want to log.
 * @return boolean success of write.
 */
    function write($type, $message) {
        $debugTypes = array('notice', 'info', 'debug');

        if ($type == 'error' || $type == 'warning') {
            $filename = $this->_path  . 'error.log';
        } elseif (in_array($type, $debugTypes)) {
            $filename = $this->_path . 'debug.log';
        } else {
            $filename = $this->_path . $type . '.log';
        }
        $output = date('Y-m-d H:i:s') . ' ' . ucfirst($type) . ': ' . $message . "\n";
        $log = new File($filename, true);
        if ($log->writable()) {
            return $log->append($output);
        }
    }
}

解决方案

Ok, this time I focused better and here's one possible problem/solution:

Can you post this file too: /var/www/html/myproject/cake/libs/log/file_log.php as it seems that error happens here and not in AES.php:

Fatal error: Class declarations may not be nested in /var/www/html/myproject/cake/libs/log/file_log.php on line 30

I think that Notice and Fatal Error are two different things that should not be mixed together. There is one notice about too big integer value (which is converted to float) and other fatal error about nesting classes inside each other.

How Aes and AesCtr should used:

Both Aes and AesCtr are fully static classes so ther's no point to instantiate them:

Change:

$aes = new AesCtr();
$decrypted = $aes->decrypt($encrypted, "mykey", 128); 

To:

$decrypted = AesCtr::decrypt($encrypted, "mykey", 128);

Yes you should drop $aes = new AesCtr(); as it is not needed when calling only static functions.

Here's about notice, AES.php line 230:

In AES.php at line 230 there is hex number 0x100000000 which is not valid signed 32-bit integer (in fact, it requires at least 33 bits even if unsigned), some PHP versions will throw an error or notice about it (older mostly). I am using PHP 5.3 and it will not notice anything even with error_reporting(E_ALL);

Signed integer maximum value is 2147483647 or in hex 0x7FFFFFFF and AES.php tries to use value of 4294967296 which is converted to floating point.

And, as language.types.integer.php says: There is no integer division operator in PHP. so that value should be converted to float anyway.

I think that problem is, as stated in error message Hex number is too big: 0x100000000, that php tries to use that hex value as integer but it is too big so it is converted to float first.

Some tests:

var_dump(0x100000000);
var_dump((int)0x100000000);

Output in 32bit system:

float(4294967296)
int(0)

And same with 64bit system:

int(4294967296)
int(4294967296)

How to fix it then?

Here's solution which may or may not work:

Simply replace 0x100000000 with 4294967296.0 so that line 230 will be like this:

for ($c=0; $c<4; $c++) $counterBlock[15-$c-4] = self::urs($b/4294967296.0, $c*8);

Maybe you should also check what urs() tries to do and how it try to do that. However it should already expecting floating point values as arguments, see integer division.

Update:

Checked that urs() seems to expect int as first arg, however it gets that from (x/y) operation which in PHP returns float if there is fractions and int otherwise.

To make it int again is simple type conversion using (int)(x/y), there is no drawbacks (or very little) compared to old way, this is only to convert it back.

Originally, before modifications, there was same possibility and propability of conversion to float as there is now (urs() doc says that first arg should be int).

for ($c=0; $c<4; $c++) $counterBlock[15-$c-4] = self::urs((int)($b/4294967296.0), $c*8);

Update: file_log.php

I think that there is nothing wrong with file_log.php, it declares class FileLog which is properly implemented and closed as far as i can see.

Other thing about file_log.php is that it seems that it is cakephp's internal library and loaded by cakephp framework. And I don't know anything about cakephp...

However, you really should test your code without AES.php or maybe try including AES.php some other way like this way to test if App::import() does not work correctly:

/* Remember to take into account that filenames are propably
 * case sensitive at server, but maybe case insensitive at
 * your workstation (if developing under windows). */

// If needed, change vendors/AES/AES.php to correct path:
require_once 'vendors/AES/AES.php';
$decrypted = AesCtr::decrypt($encrypted, "mykey", 128);

or maybe (from cakephp manual):

// Vendor not vendor and AES/AES not aes/AES or aes/aes just to be sure...
App::import('Vendor', 'AES/AES');
$decrypted = AesCtr::decrypt($encrypted, "mykey", 128);

or maybe drop it completely out:

$decrypted = 'dummytest';

or maybe include without using it at all:

App::import('vendor', 'aes', array('file' => 'AES/AES.php'));
$decrypted = 'dummytest';

instead of:

App::import('vendor', 'aes', array('file' => 'AES/AES.php'));
$decrypted = AesCtr::decrypt($encrypted, "mykey", 128);

This way problem is narrowed down, if same error still happens to pop up then problem is somewhere else but if error disappears after this test, then we know that error is either in App::import() or propably somewhere in cakephp framework.

这篇关于PHP - 类声明可能不是嵌套的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆