php5.6的key長度要求是32位元組的,你這個明顯不滿足要求的。
參考以下寫法:
<?php
# --- ENCRYPTION ---
# the key should be random binary, use scrypt, bcrypt or PBKDF2 to
# convert a string into a key
# key is specified using hexadecimal
$key = pack('H*', "");
# show key size use either 16, 24 or 32 byte keys for AES-128, 192
# and 256 respectively
$key_size = strlen($key);
echo "Key size: " . $key_size . "\n";
$plaintext = "This string was AES-256 / CBC / ZeroBytePadding encrypted.";
# create a random IV to use with CBC encoding
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
# creates a cipher text compatible with AES (Rijndael block size = 128)
# to keep the text confidential
# only suitable for encoded input that never ends with value 00h
# (because of default zero padding)
$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key,
$plaintext, MCRYPT_MODE_CBC, $iv);
# prepend the IV for it to be available for decryption
$ciphertext = $iv . $ciphertext;
# encode the resulting cipher text so it can be represented by a string
$ciphertext_base64 = base64_encode($ciphertext);
echo $ciphertext_base64 . "\n";
# === WARNING ===
# Resulting cipher text has no integrity or authenticity added
# and is not protected against padding oracle attacks.
# --- DECRYPTION ---
$ciphertext_dec = base64_decode($ciphertext_base64);
# retrieves the IV, iv_size should be created using mcrypt_get_iv_size()
$iv_dec = substr($ciphertext_dec, 0, $iv_size);
# retrieves the cipher text (everything except the $iv_size in the front)
$ciphertext_dec = substr($ciphertext_dec, $iv_size);
# may remove 00h valued characters from end of plain text
$plaintext_dec = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key,
$ciphertext_dec, MCRYPT_MODE_CBC, $iv_dec);
echo $plaintext_dec . "\n";
?>
『貳』 前端JS AES加密 後端PHP AES加解密
<!DOCTYPEhtml>
<html>
<head>
<title>aes demo</title>
</head>
<body>
<script type="text/javascript" src="./CryptoJS/aes.js"></script>
<script type="text/javascript" src="./CryptoJS/pad-zeropadding.js"></script>
<script type="text/javascript">
text = 'did=12345dg&version=1';
var key = '';
key = CryptoJS.enc.Utf8.parse(key);
var iv = "";
iv = CryptoJS.enc.Utf8.parse(iv);
var encrypted = CryptoJS.AES.encrypt(text, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.ZeroPadding
}).toString()
document.write(encrypted);
</script>
</body>
</html>
後端
public function encrypt2($input = ''){
$pk = "";
$iv = substr("", 0, 16);
// $t = 'T10515';
$encrypted = ( mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $pk, $input, MCRYPT_MODE_CBC,$iv) );
return base64_encode($encrypted);
}
public function decrypt2($encrypted){
$pk = "";
$iv = substr("", 0, 16);
// $t = 'T10515';
// $encrypted = "b7y/JPJFNTfxNVR8H4NNtw==";
return mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $pk, base64_decode($encrypted), MCRYPT_MODE_CBC, $iv);
}
可以推斷, js 部分實際只使用了 iv 的 16 位長度
ps:
js加密後默認會base64_encode
使用php解密需要base64_decode後才一致
所以使用js加密和php解密時候需要注意,php端要先base64_decode再解密,例:
js加密的串是$t=b7y/JPJFNTfxNVR8H4NNtw==
php需要
$password= trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $pk,base64_decode( $t), MCRYPT_MODE_CBC, $iv));
則$password才能正確解析出來
需要引入的兩個js文件
ase.js
[javascript] view plain
/*
CryptoJS v3.1.2
code.google.com/p/crypto-js
(c) 2009-2013 by Jeff Mott. All rights reserved.
code.google.com/p/crypto-js/wiki/License
*/
var CryptoJS=CryptoJS||function(u,p){var d={},l=d.lib={},s=function(){},t=l.Base={extend:function(a){s.prototype=this;var c=new s;a&&c.mixIn(a);c.hasOwnProperty("init")||(c.init=function(){c.$super.init.apply(this,arguments)});c.init.prototype=c;c.$super=this;return c},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var c in a)a.hasOwnProperty(c)&&(this[c]=a[c]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}},
r=l.WordArray=t.extend({init:function(a,c){a=this.words=a||[];this.sigBytes=c!=p?c:4*a.length},toString:function(a){return(a||v).stringify(this)},concat:function(a){var c=this.words,e=a.words,j=this.sigBytes;a=a.sigBytes;this.clamp();if(j%4)for(var k=0;k<a;k++)c[j+k>>>2]|=(e[k>>>2]>>>24-8*(k%4)&255)<<24-8*((j+k)%4);else if(65535<e.length)for(k=0;k<a;k+=4)c[j+k>>>2]=e[k>>>2];else c.push.apply(c,e);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<<
32-8*(c%4);a.length=u.ceil(c/4)},clone:function(){var a=t.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],e=0;e<a;e+=4)c.push(4294967296*u.random()|0);return new r.init(c,a)}}),w=d.enc={},v=w.Hex={stringify:function(a){var c=a.words;a=a.sigBytes;for(var e=[],j=0;j<a;j++){var k=c[j>>>2]>>>24-8*(j%4)&255;e.push((k>>>4).toString(16));e.push((k&15).toString(16))}return e.join("")},parse:function(a){for(var c=a.length,e=[],j=0;j<c;j+=2)e[j>>>3]|=parseInt(a.substr(j,
2),16)<<24-4*(j%8);return new r.init(e,c/2)}},b=w.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var e=[],j=0;j<a;j++)e.push(String.fromCharCode(c[j>>>2]>>>24-8*(j%4)&255));return e.join("")},parse:function(a){for(var c=a.length,e=[],j=0;j<c;j++)e[j>>>2]|=(a.charCodeAt(j)&255)<<24-8*(j%4);return new r.init(e,c)}},x=w.Utf8={stringify:function(a){try{return decodeURIComponent(escape(b.stringify(a)))}catch(c){throw Error("Malformed UTF-8 data");}},parse:function(a){return b.parse(unescape(encodeURIComponent(a)))}},
q=l.BufferedBlockAlgorithm=t.extend({reset:function(){this._data=new r.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=x.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var c=this._data,e=c.words,j=c.sigBytes,k=this.blockSize,b=j/(4*k),b=a?u.ceil(b):u.max((b|0)-this._minBufferSize,0);a=b*k;j=u.min(4*a,j);if(a){for(var q=0;q<a;q+=k)this._doProcessBlock(e,q);q=e.splice(0,a);c.sigBytes-=j}return new r.init(q,j)},clone:function(){var a=t.clone.call(this);
a._data=this._data.clone();return a},_minBufferSize:0});l.Hasher=q.extend({cfg:t.extend(),init:function(a){this.cfg=this.cfg.extend(a);this.reset()},reset:function(){q.reset.call(this);this._doReset()},update:function(a){this._append(a);this._process();return this},finalize:function(a){a&&this._append(a);return this._doFinalize()},blockSize:16,_createHelper:function(a){return function(b,e){return(new a.init(e)).finalize(b)}},_createHmacHelper:function(a){return function(b,e){return(new n.HMAC.init(a,
e)).finalize(b)}}});var n=d.algo={};return d}(Math);
(function(){var u=CryptoJS,p=u.lib.WordArray;u.enc.Base64={stringify:function(d){var l=d.words,p=d.sigBytes,t=this._map;d.clamp();d=[];for(var r=0;r<p;r+=3)for(var w=(l[r>>>2]>>>24-8*(r%4)&255)<<16|(l[r+1>>>2]>>>24-8*((r+1)%4)&255)<<8|l[r+2>>>2]>>>24-8*((r+2)%4)&255,v=0;4>v&&r+0.75*v<p;v++)d.push(t.charAt(w>>>6*(3-v)&63));if(l=t.charAt(64))for(;d.length%4;)d.push(l);return d.join("")},parse:function(d){var l=d.length,s=this._map,t=s.charAt(64);t&&(t=d.indexOf(t),-1!=t&&(l=t));for(var t=[],r=0,w=0;w<
l;w++)if(w%4){var v=s.indexOf(d.charAt(w-1))<<2*(w%4),b=s.indexOf(d.charAt(w))>>>6-2*(w%4);t[r>>>2]|=(v|b)<<24-8*(r%4);r++}return p.create(t,r)},_map:"+/="}})();
(function(u){function p(b,n,a,c,e,j,k){b=b+(n&a|~n&c)+e+k;return(b<<j|b>>>32-j)+n}function d(b,n,a,c,e,j,k){b=b+(n&c|a&~c)+e+k;return(b<<j|b>>>32-j)+n}function l(b,n,a,c,e,j,k){b=b+(n^a^c)+e+k;return(b<<j|b>>>32-j)+n}function s(b,n,a,c,e,j,k){b=b+(a^(n|~c))+e+k;return(b<<j|b>>>32-j)+n}for(var t=CryptoJS,r=t.lib,w=r.WordArray,v=r.Hasher,r=t.algo,b=[],x=0;64>x;x++)b[x]=4294967296*u.abs(u.sin(x+1))|0;r=r.MD5=v.extend({_doReset:function(){this._hash=new w.init([1732584193,4023233417,2562383102,271733878])},
_doProcessBlock:function(q,n){for(var a=0;16>a;a++){var c=n+a,e=q[c];q[c]=(e<<8|e>>>24)&16711935|(e<<24|e>>>8)&4278255360}var a=this._hash.words,c=q[n+0],e=q[n+1],j=q[n+2],k=q[n+3],z=q[n+4],r=q[n+5],t=q[n+6],w=q[n+7],v=q[n+8],A=q[n+9],B=q[n+10],C=q[n+11],u=q[n+12],D=q[n+13],E=q[n+14],x=q[n+15],f=a[0],m=a[1],g=a[2],h=a[3],f=p(f,m,g,h,c,7,b[0]),h=p(h,f,m,g,e,12,b[1]),g=p(g,h,f,m,j,17,b[2]),m=p(m,g,h,f,k,22,b[3]),f=p(f,m,g,h,z,7,b[4]),h=p(h,f,m,g,r,12,b[5]),g=p(g,h,f,m,t,17,b[6]),m=p(m,g,h,f,w,22,b[7]),
f=p(f,m,g,h,v,7,b[8]),h=p(h,f,m,g,A,12,b[9]),g=p(g,h,f,m,B,17,b[10]),m=p(m,g,h,f,C,22,b[11]),f=p(f,m,g,h,u,7,b[12]),h=p(h,f,m,g,D,12,b[13]),g=p(g,h,f,m,E,17,b[14]),m=p(m,g,h,f,x,22,b[15]),f=d(f,m,g,h,e,5,b[16]),h=d(h,f,m,g,t,9,b[17]),g=d(g,h,f,m,C,14,b[18]),m=d(m,g,h,f,c,20,b[19]),f=d(f,m,g,h,r,5,b[20]),h=d(h,f,m,g,B,9,b[21]),g=d(g,h,f,m,x,14,b[22]),m=d(m,g,h,f,z,20,b[23]),f=d(f,m,g,h,A,5,b[24]),h=d(h,f,m,g,E,9,b[25]),g=d(g,h,f,m,k,14,b[26]),m=d(m,g,h,f,v,20,b[27]),f=d(f,m,g,h,D,5,b[28]),h=d(h,f,
m,g,j,9,b[29]),g=d(g,h,f,m,w,14,b[30]),m=d(m,g,h,f,u,20,b[31]),f=l(f,m,g,h,r,4,b[32]),h=l(h,f,m,g,v,11,b[33]),g=l(g,h,f,m,C,16,b[34]),m=l(m,g,h,f,E,23,b[35]),f=l(f,m,g,h,e,4,b[36]),h=l(h,f,m,g,z,11,b[37]),g=l(g,h,f,m,w,16,b[38]),m=l(m,g,h,f,B,23,b[39]),f=l(f,m,g,h,D,4,b[40]),h=l(h,f,m,g,c,11,b[41]),g=l(g,h,f,m,k,16,b[42]),m=l(m,g,h,f,t,23,b[43]),f=l(f,m,g,h,A,4,b[44]),h=l(h,f,m,g,u,11,b[45]),g=l(g,h,f,m,x,16,b[46]),m=l(m,g,h,f,j,23,b[47]),f=s(f,m,g,h,c,6,b[48]),h=s(h,f,m,g,w,10,b[49]),g=s(g,h,f,m,
E,15,b[50]),m=s(m,g,h,f,r,21,b[51]),f=s(f,m,g,h,u,6,b[52]),h=s(h,f,m,g,k,10,b[53]),g=s(g,h,f,m,B,15,b[54]),m=s(m,g,h,f,e,21,b[55]),f=s(f,m,g,h,v,6,b[56]),h=s(h,f,m,g,x,10,b[57]),g=s(g,h,f,m,t,15,b[58]),m=s(m,g,h,f,D,21,b[59]),f=s(f,m,g,h,z,6,b[60]),h=s(h,f,m,g,C,10,b[61]),g=s(g,h,f,m,j,15,b[62]),m=s(m,g,h,f,A,21,b[63]);a[0]=a[0]+f|0;a[1]=a[1]+m|0;a[2]=a[2]+g|0;a[3]=a[3]+h|0},_doFinalize:function(){var b=this._data,n=b.words,a=8*this._nDataBytes,c=8*b.sigBytes;n[c>>>5]|=128<<24-c%32;var e=u.floor(a/
4294967296);n[(c+64>>>9<<4)+15]=(e<<8|e>>>24)&16711935|(e<<24|e>>>8)&4278255360;n[(c+64>>>9<<4)+14]=(a<<8|a>>>24)&16711935|(a<<24|a>>>8)&4278255360;b.sigBytes=4*(n.length+1);this._process();b=this._hash;n=b.words;for(a=0;4>a;a++)c=n[a],n[a]=(c<<8|c>>>24)&16711935|(c<<24|c>>>8)&4278255360;return b},clone:function(){var b=v.clone.call(this);b._hash=this._hash.clone();return b}});t.MD5=v._createHelper(r);t.HmacMD5=v._createHmacHelper(r)})(Math);
(function(){var u=CryptoJS,p=u.lib,d=p.Base,l=p.WordArray,p=u.algo,s=p.EvpKDF=d.extend({cfg:d.extend({keySize:4,hasher:p.MD5,iterations:1}),init:function(d){this.cfg=this.cfg.extend(d)},compute:function(d,r){for(var p=this.cfg,s=p.hasher.create(),b=l.create(),u=b.words,q=p.keySize,p=p.iterations;u.length<q;){n&&s.update(n);var n=s.update(d).finalize(r);s.reset();for(var a=1;a<p;a++)n=s.finalize(n),s.reset();b.concat(n)}b.sigBytes=4*q;return b}});u.EvpKDF=function(d,l,p){return s.create(p).compute(d,
l)}})();
CryptoJS.lib.Cipher||function(u){var p=CryptoJS,d=p.lib,l=d.Base,s=d.WordArray,t=d.BufferedBlockAlgorithm,r=p.enc.Base64,w=p.algo.EvpKDF,v=d.Cipher=t.extend({cfg:l.extend(),createEncryptor:function(e,a){return this.create(this._ENC_XFORM_MODE,e,a)},createDecryptor:function(e,a){return this.create(this._DEC_XFORM_MODE,e,a)},init:function(e,a,b){this.cfg=this.cfg.extend(b);this._xformMode=e;this._key=a;this.reset()},reset:function(){t.reset.call(this);this._doReset()},process:function(e){this._append(e);return this._process()},
finalize:function(e){e&&this._append(e);return this._doFinalize()},keySize:4,ivSize:4,_ENC_XFORM_MODE:1,_DEC_XFORM_MODE:2,_createHelper:function(e){return{encrypt:function(b,k,d){return("string"==typeof k?c:a).encrypt(e,b,k,d)},decrypt:function(b,k,d){return("string"==typeof k?c:a).decrypt(e,b,k,d)}}}});d.StreamCipher=v.extend({_doFinalize:function(){return this._process(!0)},blockSize:1});var b=p.mode={},x=function(e,a,b){var c=this._iv;c?this._iv=u:c=this._prevBlock;for(var d=0;d<b;d++)e[a+d]^=
c[d]},q=(d.BlockCipherMode=l.extend({createEncryptor:function(e,a){return this.Encryptor.create(e,a)},createDecryptor:function(e,a){return this.Decryptor.create(e,a)},init:function(e,a){this._cipher=e;this._iv=a}})).extend();q.Encryptor=q.extend({processBlock:function(e,a){var b=this._cipher,c=b.blockSize;x.call(this,e,a,c);b.encryptBlock(e,a);this._prevBlock=e.slice(a,a+c)}});q.Decryptor=q.extend({processBlock:function(e,a){var b=this._cipher,c=b.blockSize,d=e.slice(a,a+c);b.decryptBlock(e,a);x.call(this,
e,a,c);this._prevBlock=d}});b=b.CBC=q;q=(p.pad={}).Pkcs7={pad:function(a,b){for(var c=4*b,c=c-a.sigBytes%c,d=c<<24|c<<16|c<<8|c,l=[],n=0;n<c;n+=4)l.push(d);c=s.create(l,c);a.concat(c)},unpad:function(a){a.sigBytes-=a.words[a.sigBytes-1>>>2]&255}};d.BlockCipher=v.extend({cfg:v.cfg.extend({mode:b,padding:q}),reset:function(){v.reset.call(this);var a=this.cfg,b=a.iv,a=a.mode;if(this._xformMode==this._ENC_XFORM_MODE)var c=a.createEncryptor;else c=a.createDecryptor,this._minBufferSize=1;this._mode=c.call(a,
this,b&&b.words)},_doProcessBlock:function(a,b){this._mode.processBlock(a,b)},_doFinalize:function(){var a=this.cfg.padding;if(this._xformMode==this._ENC_XFORM_MODE){a.pad(this._data,this.blockSize);var b=this._process(!0)}else b=this._process(!0),a.unpad(b);return b},blockSize:4});var n=d.CipherParams=l.extend({init:function(a){this.mixIn(a)},toString:function(a){return(a||this.formatter).stringify(this)}}),b=(p.format={}).OpenSSL={stringify:function(a){var b=a.ciphertext;a=a.salt;return(a?s.create([1398893684,
1701076831]).concat(a).concat(b):b).toString(r)},parse:function(a){a=r.parse(a);var b=a.words;if(1398893684==b[0]&&1701076831==b[1]){var c=s.create(b.slice(2,4));b.splice(0,4);a.sigBytes-=16}return n.create({ciphertext:a,salt:c})}},a=d.SerializableCipher=l.extend({cfg:l.extend({format:b}),encrypt:function(a,b,c,d){d=this.cfg.extend(d);var l=a.createEncryptor(c,d);b=l.finalize(b);l=l.cfg;return n.create({ciphertext:b,key:c,iv:l.iv,algorithm:a,mode:l.mode,padding:l.padding,blockSize:a.blockSize,formatter:d.format})},
decrypt:function(a,b,c,d){d=this.cfg.extend(d);b=this._parse(b,d.format);return a.createDecryptor(c,d).finalize(b.ciphertext)},_parse:function(a,b){return"string"==typeof a?b.parse(a,this):a}}),p=(p.kdf={}).OpenSSL={execute:function(a,b,c,d){d||(d=s.random(8));a=w.create({keySize:b+c}).compute(a,d);c=s.create(a.words.slice(b),4*c);a.sigBytes=4*b;return n.create({key:a,iv:c,salt:d})}},c=d.PasswordBasedCipher=a.extend({cfg:a.cfg.extend({kdf:p}),encrypt:function(b,c,d,l){l=this.cfg.extend(l);d=l.kdf.execute(d,
b.keySize,b.ivSize);l.iv=d.iv;b=a.encrypt.call(this,b,c,d.key,l);b.mixIn(d);return b},decrypt:function(b,c,d,l){l=this.cfg.extend(l);c=this._parse(c,l.format);d=l.kdf.execute(d,b.keySize,b.ivSize,c.salt);l.iv=d.iv;return a.decrypt.call(this,b,c,d.key,l)}})}();
(function(){for(var u=CryptoJS,p=u.lib.BlockCipher,d=u.algo,l=[],s=[],t=[],r=[],w=[],v=[],b=[],x=[],q=[],n=[],a=[],c=0;256>c;c++)a[c]=128>c?c<<1:c<<1^283;for(var e=0,j=0,c=0;256>c;c++){var k=j^j<<1^j<<2^j<<3^j<<4,k=k>>>8^k&255^99;l[e]=k;s[k]=e;var z=a[e],F=a[z],G=a[F],y=257*a[k]^16843008*k;t[e]=y<<24|y>>>8;r[e]=y<<16|y>>>16;w[e]=y<<8|y>>>24;v[e]=y;y=16843009*G^65537*F^257*z^16843008*e;b[k]=y<<24|y>>>8;x[k]=y<<16|y>>>16;q[k]=y<<8|y>>>24;n[k]=y;e?(e=z^a[a[a[G^z]]],j^=a[a[j]]):e=j=1}var H=[0,1,2,4,8,
16,32,64,128,27,54],d=d.AES=p.extend({_doReset:function(){for(var a=this._key,c=a.words,d=a.sigBytes/4,a=4*((this._nRounds=d+6)+1),e=this._keySchele=[],j=0;j<a;j++)if(j<d)e[j]=c[j];else{var k=e[j-1];j%d?6<d&&4==j%d&&(k=l[k>>>24]<<24|l[k>>>16&255]<<16|l[k>>>8&255]<<8|l[k&255]):(k=k<<8|k>>>24,k=l[k>>>24]<<24|l[k>>>16&255]<<16|l[k>>>8&255]<<8|l[k&255],k^=H[j/d|0]<<24);e[j]=e[j-d]^k}c=this._invKeySchele=[];for(d=0;d<a;d++)j=a-d,k=d%4?e[j]:e[j-4],c[d]=4>d||4>=j?k:b[l[k>>>24]]^x[l[k>>>16&255]]^q[l[k>>>
8&255]]^n[l[k&255]]},encryptBlock:function(a,b){this._doCryptBlock(a,b,this._keySchele,t,r,w,v,l)},decryptBlock:function(a,c){var d=a[c+1];a[c+1]=a[c+3];a[c+3]=d;this._doCryptBlock(a,c,this._invKeySchele,b,x,q,n,s);d=a[c+1];a[c+1]=a[c+3];a[c+3]=d},_doCryptBlock:function(a,b,c,d,e,j,l,f){for(var m=this._nRounds,g=a[b]^c[0],h=a[b+1]^c[1],k=a[b+2]^c[2],n=a[b+3]^c[3],p=4,r=1;r<m;r++)var q=d[g>>>24]^e[h>>>16&255]^j[k>>>8&255]^l[n&255]^c[p++],s=d[h>>>24]^e[k>>>16&255]^j[n>>>8&255]^l[g&255]^c[p++],t=
d[k>>>24]^e[n>>>16&255]^j[g>>>8&255]^l[h&255]^c[p++],n=d[n>>>24]^e[g>>>16&255]^j[h>>>8&255]^l[k&255]^c[p++],g=q,h=s,k=t;q=(f[g>>>24]<<24|f[h>>>16&255]<<16|f[k>>>8&255]<<8|f[n&255])^c[p++];s=(f[h>>>24]<<24|f[k>>>16&255]<<16|f[n>>>8&255]<<8|f[g&255])^c[p++];t=(f[k>>>24]<<24|f[n>>>16&255]<<16|f[g>>>8&255]<<8|f[h&255])^c[p++];n=(f[n>>>24]<<24|f[g>>>16&255]<<16|f[h>>>8&255]<<8|f[k&255])^c[p++];a[b]=q;a[b+1]=s;a[b+2]=t;a[b+3]=n},keySize:8});u.AES=p._createHelper(d)})();
pad-zeropadding.js
/*
CryptoJS v3.1.2
code.google.com/p/crypto-js
(c) 2009-2013 by Jeff Mott. All rights reserved.
code.google.com/p/crypto-js/wiki/License
*/
/**
* Zero padding strategy.
*/
CryptoJS.pad.ZeroPadding = {
pad: function (data, blockSize) {
// Shortcut
var blockSizeBytes = blockSize * 4;
// Pad
data.clamp();
data.sigBytes += blockSizeBytes - ((data.sigBytes % blockSizeBytes) || blockSizeBytes);
},
unpad: function (data) {
// Shortcut
var dataWords = data.words;
// Unpad
var i = data.sigBytes - 1;
while (!((dataWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff)) {
i--;
}
data.sigBytes = i + 1;
}
};
『叄』 請詳細說明一下php5中的魔術方法
PHP處理對象部分的內核完全重新開發過,提供更多功能的同時也提高了性能。在以前版本的php中,處理對象和處理基本類型(數字,字元串)的方式是一樣的。這種方式的缺陷是:當將對象賦值給一個變數時,或者通過參數傳遞對象時,對象將被完全拷貝一份。在新的版本里,上述操作將傳遞引用(可以把引用理解成對象的標識符),而非值。
很多PHP程序員可能甚至沒有察覺到老的對象處理方式。事實上,大多數的php應用都可以很好地運行。或者僅僅需要很少的改動。
私有和受保護成員
PHP5引入了私有和受保護成員變數的概念。我們可以用它來定義類成員的可見性。
例子
受保護成員可以被子類訪問, 而私有成員只能被類本身訪問。
代碼:--------------------------------------------------------------------------------
<?php
class MyClass {
private $Hello = "Hello, World!\n";
protected $Bar = "Hello, Foo!\n";
protected $Foo = "Hello, Bar!\n";
function printHello() {
print "MyClass::printHello() " . $this->Hello;
print "MyClass::printHello() " . $this->Bar;
print "MyClass::printHello() " . $this->Foo;
}
}
class MyClass2 extends MyClass {
protected $Foo;
function printHello() {
MyClass::printHello(); /* Should print */
print "MyClass2::printHello() " . $this->Hello; /* Shouldn't print out anything */
print "MyClass2::printHello() " . $this->Bar; /* Shouldn't print (not declared)*/
print "MyClass2::printHello() " . $this->Foo; /* Should print */
}
}
$obj = new MyClass();
print $obj->Hello; /* Shouldn't print out anything */
print $obj->Bar; /* Shouldn't print out anything */
print $obj->Foo; /* Shouldn't print out anything */
$obj->printHello(); /* Should print */
$obj = new MyClass2();
print $obj->Hello; /* Shouldn't print out anything */
print $obj->Bar; /* Shouldn't print out anything */
print $obj->Foo; /* Shouldn't print out anything */
$obj->printHello();
?>
--------------------------------------------------------------------------------
私有方法和受保護方法
PHP5也引入了私有方法和受保護方法的概念。
例子:
代碼:--------------------------------------------------------------------------------
<?php
class Foo {
private function aPrivateMethod() {
echo "Foo::aPrivateMethod() called.\n";
}
protected function aProtectedMethod() {
echo "Foo::aProtectedMethod() called.\n";
$this->aPrivateMethod();
}
}
class Bar extends Foo {
public function aPublicMethod() {
echo "Bar::aPublicMethod() called.\n";
$this->aProtectedMethod();
}
}
$o = new Bar;
$o->aPublicMethod();
?>
--------------------------------------------------------------------------------
以前的不使用類的老代碼,沒有訪問修飾符(public, protected, private)的代碼可以不經改動運行。
抽象類和抽象方法
Php5也引入了抽象類和抽象方法的概念。抽象方法只是聲明了方法的簽名並不提供它的實現。包含抽象方法的類必須被聲明成抽象類。
例子:
代碼:--------------------------------------------------------------------------------
<?php
abstract class AbstractClass {
abstract public function test();
}
class ImplementedClass extends AbstractClass {
public function test() {
echo "ImplementedClass::test() called.\n";
}
}
$o = new ImplementedClass;
$o->test();
?>
--------------------------------------------------------------------------------
抽象類不能被實例化。以前的不使用抽象類的老代碼可以不經改動運行。
介面
Php5引入了介面。一個類可以實現多個介面。
例子:
代碼:--------------------------------------------------------------------------------
<?php
interface Throwable {
public function getMessage();
}
class MyException implements Throwable {
public function getMessage() {
// ...
}
}
?>
--------------------------------------------------------------------------------
以前的不使用介面的老代碼可以不經改動運行
類的型別提示
PHP5依然是弱類型的,不過在定義函數參數時,可以使用類的型別提示來聲明期望傳入的對象類型
Example
代碼:--------------------------------------------------------------------------------
<?php
interface Foo {
function a(Foo $foo);
}
interface Bar {
function b(Bar $bar);
}
class FooBar implements Foo, Bar {
function a(Foo $foo) {
// ...
}
function b(Bar $bar) {
// ...
}
}
$a = new FooBar;
$b = new FooBar;
$a->a($b);
$a->b($b);
?>
--------------------------------------------------------------------------------
和其他強類型語言一樣,php5類的型別提示在運行期間檢查而非編譯期間檢查。即:
代碼:--------------------------------------------------------------------------------
<?php
function foo(ClassName $object) {
// ...
}
?>
和下面的代碼是一樣的:
<?php
function foo($object) {
if (!($object instanceof ClassName)) {
die("Argument 1 must be an instance of ClassName");
}
}
?>
--------------------------------------------------------------------------------
這個語法只適用於類,不適用於內建類型。
Final
PHP 5 引入了final關鍵字來聲明final成員和final方法。final成員和final方法不能被子類覆蓋。
Example
代碼:--------------------------------------------------------------------------------
<?php
class Foo {
final function bar() {
// ...
}
}
?>
--------------------------------------------------------------------------------
更進一步,可以把類聲明成final。將類聲明成final可以阻止這個類被繼承。final類裡面的方法預設地都是final的,無需再聲明一次。
Example
代碼:--------------------------------------------------------------------------------
<?php
final class Foo {
// class definition
}
// the next line is impossible
// class Bork extends Foo {}
?>
--------------------------------------------------------------------------------
屬性不能定義成為final.
以前的不使用final的老代碼可以不經改動運行.
對象克隆
Php4沒有提供一種機制來讓用戶自己定義復制構造子( constructor)控制對象的復制過程。Php4做二進制的拷貝,因而很精確地復制了對象的所有屬性。
精確地復制對象的所有屬性可能並不是我們一直想要的。有個例子可以很好地說明我們確實需要復制構造子:比如一個GTK Window的對象 a。 a持有它所需要的全部資源。當復制的這個GTK Window到對象b時候,我們更希望b持有新的資源對象。再舉個例子:對象a包含了一個對象c, 當你把對象a 復制到對象c的時候。我們可能更希望對象b包含一個新的對象c的, 而不是一個對象c的引用。(譯者註:這里所說的就是淺克隆和深克隆。)
對象的復制是通過clone這個關鍵字達到的(Clone調用被克隆對象的__clone()方法)。對象的__clone方法不能夠直接被調用。
代碼:--------------------------------------------------------------------------------
<?php
$_of_object = clone $object;
?>
--------------------------------------------------------------------------------
當developer創建對象的一份拷貝的時候,php5將會檢查 __clone()方法是否存在。如果不存在,那麼它就會呼叫預設的__clone()方法,復制對象的所有屬性。如果__clone()方法已經定義過,那麼_clone()方法就會負責設置新對象的屬性。為了方便起見,Engine會預設地復制所有的屬性。所以在__clone()方法中,只需要覆蓋那些需要更改的屬性就可以了。如下:
Example
代碼:--------------------------------------------------------------------------------
<?php
class MyCloneable {
static $id = 0;
function MyCloneable() {
$this->id = self::$id++;
}
function __clone() {
$this->address = "New York";
$this->id = self::$id++;
}
}
$obj = new MyCloneable();
$obj->name = "Hello";
$obj->address = "Tel-Aviv";
print $obj->id . "\n";
$obj_cloned = clone $obj;
print $obj_cloned->id . "\n";
print $obj_cloned->name . "\n";
print $obj_cloned->address . "\n";
?>
--------------------------------------------------------------------------------
統一構造函數
Php5允許開發者聲明一個類的構造方法。擁有構造方法的類在每次創建新的對象的時候都會呼叫這個方法,因此構造方法適合對象在被使用之前的初始化工作
Php4中,構造方法的名稱和類的名稱一樣。考慮到從子類構造方法呼叫父類構造方法的情況是非常普遍的,而將類從一個繼承體系中搬遷引起的父類變更就常常導致需要更改類的構造方法,php4的做法顯然是不太合理的。
Php5引入了一個聲明構建函數的標准方法: __construct().如下:
Example
代碼:--------------------------------------------------------------------------------
<?php
class BaseClass {
function __construct() {
print "In BaseClass constructor\n";
}
}
class SubClass extends BaseClass {
function __construct() {
parent::__construct();
print "In SubClass constructor\n";
}
}
$obj = new BaseClass();
$obj = new SubClass();
?>
--------------------------------------------------------------------------------
為保持向後的兼容性,如果php5不能夠找到 __construct(),它會尋找老式的構造方法,即與類同名的方法。簡單的說,只有當老代碼里包含了一個__construct()方法的時候,才存在一個兼容性的問題。
析構方法
對於面向對象的編程來說,可以定義析構方法是非常有用的一個功能。析構方法可以用來記錄調試信息,關閉資料庫連接等等一些清除收尾的工作。Php4中沒有析構方法,盡管php4已經支持可以注冊一個函數以便請求結束的時候被調用。
Php5引進的析構方法的概念和其他面向對象的語言(比如java)是一致的。當指向這個對象的最後一個引用被銷毀的時候,析構方法被調用,調用完成後釋放內存。注意:析構方法不接受任何參數。
Example
代碼:--------------------------------------------------------------------------------
<?php
class MyDestructableClass {
function __construct() {
print "In constructor\n";
$this->name = "MyDestructableClass";
}
function __destruct() {
print "Destroying " . $this->name . "\n";
}
}
$obj = new MyDestructableClass();
?>
--------------------------------------------------------------------------------
和構建方法一樣,父類的析構方法也不會被隱含調用。子類可以在自己的析構方法通過調用parent::__destruct()來顯式地調用它。
Constants
Php5引入了class級別的常量。
代碼:--------------------------------------------------------------------------------
<?php
class Foo {
const constant = "constant";
}
echo "Foo::constant = " . Foo::constant . "\n";
?>
--------------------------------------------------------------------------------
老的沒有使用const的代碼仍然正常運行。
Exceptions
Php4沒有異常控制。Php5引入了和其它語言(java)相似的異常控制模式。應該注意的是php5裡面支持捕捉全部異常,但是不支持finally子句。
在catch語句塊裡面,可以重新拋出異常。也可以有多個catch語句,在這種情況下,被捕捉到的異常從上往下依次比較和catch語句比較異常,第一個類型匹配的catch語句將會被執行。如果一直搜索到底還沒有發現匹配的catch子句,則尋找下一個try/catch語句。最後不能捕捉的異常將被顯示出來。如果異常被捕捉,那麼程序會接著catch語句塊的下面開始執行。
Example
代碼:--------------------------------------------------------------------------------
<?php
class MyException {
function __construct($exception) {
$this->exception = $exception;
}
function Display() {
print "MyException: $this->exception\n";
}
}
class MyExceptionFoo extends MyException {
function __construct($exception) {
$this->exception = $exception;
}
function Display() {
print "MyException: $this->exception\n";
}
}
try {
throw new MyExceptionFoo('Hello');
}
catch (MyException $exception) {
$exception->Display();
}
catch (Exception $exception) {
echo $exception;
}
?>
--------------------------------------------------------------------------------
上面的例子表明可以定義一個並不繼承自 Exception的異常類,但是,最好還是從Exception繼承並定義自己的異常。這是因為系統內建的Exception類能夠收集到很多有用的信息, 而不繼承它的異常類是得不到這些信息的。下面的php代碼模仿了系統內建Exception類。每個屬性後面都加了注釋。每個屬性都有一個getter,由於這些getter方法經常被系統內部處理調用,所以這些方法被標明了final。
Example
代碼:--------------------------------------------------------------------------------
<?php
class Exception {
function __construct(string $message=NULL, int code=0) {
if (func_num_args()) {
$this->message = $message;
}
$this->code = $code;
$this->file = __FILE__; // of throw clause
$this->line = __LINE__; // of throw clause
$this->trace = debug_backtrace();
$this->string = StringFormat($this);
}
protected $message = 'Unknown exception'; // exception message
protected $code = 0; // user defined exception code
protected $file; // source filename of exception
protected $line; // source line of exception
private $trace; // backtrace of exception
private $string; // internal only!!
final function getMessage() {
return $this->message;
}
final function getCode() {
return $this->code;
}
final function getFile() {
return $this->file;
}
final function getTrace() {
return $this->trace;
}
final function getTraceAsString() {
return self::TraceFormat($this);
}
function _toString() {
return $this->string;
}
static private function StringFormat(Exception $exception) {
// ... a function not available in PHP scripts
// that returns all relevant information as a string
}
static private function TraceFormat(Exception $exception) {
// ... a function not available in PHP scripts
// that returns the backtrace as a string
}
}
?>
--------------------------------------------------------------------------------
如果我們定義的一異常類都是繼承自Exception基類
無兼容性問題。老的代碼不會受到這一特性的影響。
Dereferencing objects returned from functions
Php4中不能再次引用函數返回的對象以進一步呼叫返回對象的方法,而php5是可以的。
代碼:--------------------------------------------------------------------------------
<?php
class Circle {
function draw() {
print "Circle\n";
}
}
class Square {
function draw() {
print "Square\n";
}
}
function ShapeFactoryMethod($shape) {
switch ($shape) {
case "Circle":
return new Circle();
case "Square":
return new Square();
}
}
ShapeFactoryMethod("Circle")->draw();
ShapeFactoryMethod("Square")->draw();
?>
--------------------------------------------------------------------------------
靜態成員變數能夠被初始化。
Example
代碼:--------------------------------------------------------------------------------
<?php
class foo {
static $my_static = 5;
public $my_prop = 'bla';
}
print foo::$my_static;
$obj = new foo;
print $obj->my_prop;
?>
--------------------------------------------------------------------------------
靜態方法
PHP 5 引入了靜態方法,可以在不實例化類的情況下呼叫靜態方法。
Example
代碼:--------------------------------------------------------------------------------
<?php
class Foo {
public static function aStaticMethod() {
// ...
}
}
Foo::aStaticMethod();
?>
--------------------------------------------------------------------------------
偽變數$this不能夠在靜態方法方法中使用。
instanceof
Php5引入了instanceof關鍵字,允許用它來測試一個對象是一個類的實例,或者是一個派生類的實例,或者實現了某個介面
Example
代碼:--------------------------------------------------------------------------------
<?php
class baseClass { }
$a = new baseClass;
if ($a instanceof baseClass) {
echo "Hello World";
}
?>
--------------------------------------------------------------------------------
Static function variables
現在,靜態變數在編譯階段處理。因此程序員可以通過引用為靜態變數賦值。這可以改善性能,不過,不能夠使用對靜態變數的間接引用了。
按引用傳遞的函數參數現在也可以設置預設值了。
Example
代碼:--------------------------------------------------------------------------------
<?php
function my_function(&$var = null) {
if ($var === null) {
die("$var needs to have a value");
}
}
?>
--------------------------------------------------------------------------------
__autoload()
__autoload() 攔截函數在一個未聲明的類被初始化的時候自動調用。該類的名字會被自動傳遞給__autoload()函數。而__autoload()也只有這么唯一的一個參數。
Example
代碼:--------------------------------------------------------------------------------
<?php
function __autoload($className) {
include_once $className . ".php";
}
$object = new ClassName;
?>
--------------------------------------------------------------------------------
可重載的方法呼叫和屬性訪問
方法呼叫和屬性訪問都能夠通過__call, __get() and __set()方法重載。
Example: __get() and __set()
代碼:--------------------------------------------------------------------------------
<?php
class Setter {
public $n;
public $x = array("a" => 1, "b" => 2, "c" => 3);
function __get($nm) {
print "Getting [$nm]\n";
if (isset($this->x[$nm])) {
$r = $this->x[$nm];
print "Returning: $r\n";
return $r;
} else {
print "Nothing!\n";
}
}
function __set($nm, $val) {
print "Setting [$nm] to $val\n";
if (isset($this->x[$nm])) {
$this->x[$nm] = $val;
print "OK!\n";
} else {
print "Not OK!\n";
}
}
}
$foo = new Setter();
$foo->n = 1;
$foo->a = 100;
$foo->a++;
$foo->z++;
var_mp($foo);
?>
--------------------------------------------------------------------------------
Example: __call()
代碼:--------------------------------------------------------------------------------
<?php
class Caller {
private $x = array(1, 2, 3);
function __call($m, $a) {
print "Method $m called:\n";
var_mp($a);
return $this->x;
}
}
$foo = new Caller();
$a = $foo->test(1, "2", 3.4, true);
var_mp($a);
?>
--------------------------------------------------------------------------------
迭代
當和foreach一起使用對象的時候,迭代的方式被重載過了。預設的行為是迭代類的所有屬性。
Example
代碼:--------------------------------------------------------------------------------
<?php
class Foo {
public $x = 1;
public $y = 2;
}
$obj = new Foo;
foreach ($obj as $prp_name => $prop_value) {
// using the property
}
?>
--------------------------------------------------------------------------------
一個類的所有對象都能夠被迭代瀏覽到, 如果這個類實現了一個空的介面:Traversable. 換句話說,實現了Traversable介面的類可以和foreach一起使用。
介面 IteratorAggregate 和Iterator允許指定類的對象在代碼中如何迭代。IteratorAggregate介面有一個方法:getIterator() 必須返回一個數組
Example
代碼:--------------------------------------------------------------------------------
<?php
class ObjectIterator implements Iterator {
private $obj;
private $num;
function __construct($obj) {
$this->obj = $obj;
}
function rewind() {
$this->num = 0;
}
function valid() {
return $this->num < $this->obj->max;
}
function key() {
return $this->num;
}
function current() {
switch($this->num) {
case 0: return "1st";
case 1: return "2nd";
case 2: return "3rd";
default: return $this->num."th";
}
}
function next() {
$this->num++;
}
}
class Object implements IteratorAggregate {
public $max = 3;
function getIterator() {
return new ObjectIterator($this);
}
}
$obj = new Object;
// this foreach ...
foreach($obj as $key => $val) {
echo "$key = $val\n";
}
// matches the following 7 lines with the for directive.
$it = $obj->getIterator();
for($it->rewind(); $it->hasMore(); $it->next) {
$key = $it->current();
$val = $it->key();
echo "$key = $val\n";
}
unset($it);
?>
--------------------------------------------------------------------------------
新的__toString方法
可以通過覆蓋__toString方法來控制對象到字元串的轉換。
Example
代碼:---------------------------------------
『肆』 php中多維數組的問題
"Griffin"=>array()
表示索引"Griffin"是一個數組。=>可以簡單理解為賦值。這是php里特有的一種寫法。
數組分為2種,一種是自動索引數組。比如
$x=array ("Peter","Lois", "Megan");
那麼$X[0]值為"peter",$X[1]為lois。
還有一種是自定義索引數組。
比如
$x=array ("father"=>"Peter","mother"=>"Lois","son"=> "Megan");
那麼$x["father"] 就為"peter"
用引號圍起來表示這是一個索引字元串值。通常情況下你直接[Griffin]也可以。
但是如果你在系統里有一個變數
$Griffin="son";
那麼$families[Griffin]實際上會等於$families['son']。所以最好用引號圍起來。
更多詳細可以看php手冊數組一章。
==========================================================
數組
PHP 中的 數組 實際上是一個有序映射。映射是一種把 values 關聯到 keys 的類型。此類型在很多方面做了優化,因此可以把它當成真正的數組,或列表(向量),散列表(是映射的一種實現),字典,集合,棧,隊列以及更多可能性。數組元素的值也可以是另一個數組。樹形結構和多維數組也是允許的。
解釋這些結構超出了本手冊的范圍,但對於每種結構至少會提供一個例子。要得到這些結構的更多信息,建議參考有關此廣闊主題的其它著作。
語法
定義數組 array()
可以用 array() 語言結構來新建一個 array。它接受任意數量用逗號分隔的 鍵(key) => 值(value) 對。
array( key => value
, ...
)
// 鍵(key) 可是是一個 整數(integer) 或 字元串(string)
// 值(value) 可以是任意類型的值<?php
$arr = array("foo" => "bar", 12 => true);
echo $arr["foo"]; // bar
echo $arr[12]; // 1
?>
key 可以是 integer 或者 string。如果key是一個 integer 的標准表示,則被解釋為整數(例如 "8" 將被解釋為 8,而 "08" 將被解釋為 "08")。key 中的浮點數被取整為 integer。在 PHP 中索引數組與關聯 數組 是相同的,它們都可以同時包含 整型 和 字元串 的下標。
值可以是任意的 PHP 類型。
<?php
$arr = array("somearray" => array(6 => 5, 13 => 9, "a" => 42));
echo $arr["somearray"][6]; // 5
echo $arr["somearray"][13]; // 9
echo $arr["somearray"]["a"]; // 42
?>
如果對給出的值沒有指定鍵名,則取當前最大的整數索引值,而新的鍵名將是該值加一。如果指定的鍵名已經有了值,則該值會被覆蓋。
<?php
// 這個數組與下面的數組相同 ...
array(5 => 43, 32, 56, "b" => 12);
// ...
array(5 => 43, 6 => 32, 7 => 56, "b" => 12);
?>
Warning
自 PHP 4.3.0 起,上述的索引生成方法改變了。如今如果給一個當前最大鍵名是負值的數組添加一個新值,則新生成的的索引將為零(0)。以前新生成的索引為當前最大索引加一,和正值的索引相同。
使用 TRUE 作為鍵名將使 integer 1 成為鍵名。使用 FALSE 作為鍵名將使 integer 0 成為鍵名。使用 NULL 作為鍵名將等同於使用空字元串。使用空字元串作為鍵名將新建(或覆蓋)一個用空字元串作為鍵名的值,這和用空的方括弧不一樣。
不能用數組和對象作為鍵(key)。這樣做會導致一個警告:Illegal offset type。
用方括弧的語法新建/修改
可以通過明示地設定值來改變一個現有的數組。
這是通過在方括弧內指定鍵名來給數組賦值實現的。也可以省略鍵名,在這種情況下給變數名加上一對空的方括弧(「[]」)。
$arr[key] = value;
$arr[] = value;
// key 可以是 integer 或 string
// value 可以是任意類型的值如果 $arr 還不存在,將會新建一個。這也是一種定義數組的替換方法。要改變一個值,只要給它賦一個新值。如果要刪除一個鍵名/值對,要對它用 unset()。
<?php
$arr = array(5 => 1, 12 => 2);
$arr[] = 56; // This is the same as $arr[13] = 56;
// at this point of the script
$arr["x"] = 42; // This adds a new element to
// the array with key "x"
unset($arr[5]); // This removes the element from the array
unset($arr); // This deletes the whole array
?>
Note:
如上所述,如果給出方括弧但沒有指定鍵名,則取當前最大整數索引值,新的鍵名將是該值 + 1。如果當前還沒有整數索引,則鍵名將為 0。如果指定的鍵名已經有值了,該值將被覆蓋。
注意這里所使用的最大整數鍵名不一定當前就在數組中。它只要在上次數組重新生成索引後曾經存在過就行了。以下面的例子來說明:
<?php
// 創建一個簡單的數組
$array = array(1, 2, 3, 4, 5);
print_r($array);
// 現在刪除其中的所有元素,但保持數組本身不變:
foreach ($array as $i => $value) {
unset($array[$i]);
}
print_r($array);
// 添加一個單元(注意新的鍵名是 5,而不是你可能以為的 0)
$array[] = 6;
print_r($array);
// 重新索引:
$array = array_values($array);
$array[] = 7;
print_r($array);
?>
以上常式會輸出:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
)
Array
(
)
Array
(
[5] => 6
)
Array
(
[0] => 6
[1] => 7
)
實用函數
有很多操作數組的函數,參見數組函數一節。
Note:
unset() 函數允許刪除數組中的某個鍵。但要注意數組將不會重建索引。 If a true "remove and shift" behavior is desired, the array can be reindexed using the array_values() function.
<?php
$a = array(1 => 'one', 2 => 'two', 3 => 'three');
unset($a[2]);
/* will proce an array that would have been defined as
$a = array(1 => 'one', 3 => 'three');
and NOT
$a = array(1 => 'one', 2 =>'three');
*/
$b = array_values($a);
// Now $b is array(0 => 'one', 1 =>'three')
?>
foreach 控制結構是專門用於數組的。它提供了一個簡單的方法來遍歷數組。
數組做什麼和不做什麼
為什麼 $foo[bar] 錯了?
應該始終在用字元串表示的數組索引上加上引號。例如用 $foo['bar'] 而不是 $foo[bar]。但是為什麼 $foo[bar] 錯了呢?可能在老的腳本中見過如下語法:
<?php
$foo[bar] = 'enemy';
echo $foo[bar];
// etc
?>
這樣是錯的,但可以正常運行。那麼為什麼錯了呢?原因是此代碼中有一個未定義的常量(bar)而不是字元串('bar'-注意引號),而 PHP 可能會在以後定義此常量,不幸的是你的代碼中有同樣的名字。它能運行,是因為 PHP 自動將裸字元串(沒有引號的字元串且不對應於任何已知符號)轉換成一個其值為該裸字元串的正常字元串。例如,如果沒有常量定義為 bar,PHP 將把它替代為 'bar' 並使用之。
Note: 這並不意味著總是給鍵名加上引號。用不著給鍵名為常量或變數的加上引號,否則會使 PHP 不能解析它們。
<?php
error_reporting(E_ALL);
ini_set('display_errors', true);
ini_set('html_errors', false);
// Simple array:
$array = array(1, 2);
$count = count($array);
for ($i = 0; $i < $count; $i++) {
echo "\nChecking $i: \n";
echo "Bad: " . $array['$i'] . "\n";
echo "Good: " . $array[$i] . "\n";
echo "Bad: {$array['$i']}\n";
echo "Good: {$array[$i]}\n";
}
?>
以上常式會輸出:
Checking 0:
Notice: Undefined index: $i in /path/to/script.html on line 9
Bad:
Good: 1
Notice: Undefined index: $i in /path/to/script.html on line 11
Bad:
Good: 1
Checking 1:
Notice: Undefined index: $i in /path/to/script.html on line 9
Bad:
Good: 2
Notice: Undefined index: $i in /path/to/script.html on line 11
Bad:
Good: 2
演示此行為的更多例子:
<?php
// Show all errors
error_reporting(E_ALL);
$arr = array('fruit' => 'apple', 'veggie' => 'carrot');
// Correct
print $arr['fruit']; // apple
print $arr['veggie']; // carrot
// Incorrect. This works but also throws a PHP error of level E_NOTICE because
// of an undefined constant named fruit
//
// Notice: Use of undefined constant fruit - assumed 'fruit' in...
print $arr[fruit]; // apple
// This defines a constant to demonstrate what's going on. The value 'veggie'
// is assigned to a constant named fruit.
define('fruit', 'veggie');
// Notice the difference now
print $arr['fruit']; // apple
print $arr[fruit]; // carrot
// The following is okay, as it's inside a string. Constants are not looked for
// within strings, so no E_NOTICE occurs here
print "Hello $arr[fruit]"; // Hello apple
// With one exception: braces surrounding arrays within strings allows constants
// to be interpreted
print "Hello {$arr[fruit]}"; // Hello carrot
print "Hello {$arr['fruit']}"; // Hello apple
// This will not work, and will result in a parse error, such as:
// Parse error: parse error, expecting T_STRING' or T_VARIABLE' or T_NUM_STRING'
// This of course applies to using superglobals in strings as well
print "Hello $arr['fruit']";
print "Hello $_GET['foo']";
// Concatenation is another option
print "Hello " . $arr['fruit']; // Hello apple
?>
當打開 error_reporting 來顯示 E_NOTICE 級別的錯誤(例如將其設為 E_ALL)時將看到這些錯誤。默認情況下 error_reporting 被關閉不顯示這些。
和在語法一節中規定的一樣,在方括弧(「[」和「]」)之間必須有一個表達式。這意味著可以這樣寫:
<?php
echo $arr[somefunc($bar)];
?>
這是一個用函數返回值作為數組索引的例子。PHP 也可以用已知常量,可能之前已經見過
<?php
$error_descriptions[E_ERROR] = "A fatal error has occured";
$error_descriptions[E_WARNING] = "PHP issued a warning";
$error_descriptions[E_NOTICE] = "This is just an informal notice";
?>
注意 E_ERROR 也是個合法的標識符,就和第一個例子中的 bar 一樣。但是上一個例子實際上和如下寫法是一樣的:
<?php
$error_descriptions[1] = "A fatal error has occured";
$error_descriptions[2] = "PHP issued a warning";
$error_descriptions[8] = "This is just an informal notice";
?>
因為 E_ERROR 等於 1, 等等.
那麼為什麼這樣做不好?
也許有一天,PHP 開發小組可能會想新增一個常量或者關鍵字,或者用戶可能希望以後在自己的程序中引入新的常量,那就有麻煩了。例如已經不能這樣用 empty 和 default 這兩個詞了,因為他們是保留字。
Note: 重申一次,在雙引號字元串中,不給索引加上引號是合法的因此 "$foo[bar]"是合法的(「合法」的原文為valid。在實際測試中,這么做確實可以訪問數組的該元素,但是會報一個常量未定義的notice。無論如何,強烈建議不要使用$foo[bar]這樣的寫法,而要使用$foo['bar']來訪問數組中元素。--haohappy注)。至於為什麼參見以上的例子和字元串中的變數解析中的解釋。
轉換為數組
對於任意類型: integer, float, string, boolean and resource,如果將一個值轉換為數組,將得到一個僅有一個元素的數組(其下標為 0),該元素即為此標量的值。換句話說, (array)$scalarValue 與 array($scalarValue) 完全一樣。
If an object is converted to an array, the result is an array whose elements are the object's properties. The keys are the member variable names, with a few notable exceptions: integer properties are unaccessible; private variables have the class name prepended to the variable name; protected variables have a '*' prepended to the variable name. These prepended values have null bytes on either side. This can result in some unexpected behaviour:
<?php
class A {
private $A; // This will become '\0A\0A'
}
class B extends A {
private $A; // This will become '\0B\0A'
public $AA; // This will become 'AA'
}
var_mp((array) new B());
?>
The above will appear to have two keys named 'AA', although one of them is actually named '\0A\0A'.
將 NULL 轉換到 數組(array) 會得到一個空的數組。
比較
可能使用 array_diff() 和數組運算符來比較數組。
Examples
PHP 中的數組類型有非常多的用途,因此這里有一些例子展示數組的完整威力。
<?php
// This:
$a = array( 'color' => 'red',
'taste' => 'sweet',
'shape' => 'round',
'name' => 'apple',
4 // key will be 0
);
$b = array('a', 'b', 'c');
// . . .is completely equivalent with this:
$a = array();
$a['color'] = 'red';
$a['taste'] = 'sweet';
$a['shape'] = 'round';
$a['name'] = 'apple';
$a[] = 4; // key will be 0
$b = array();
$b[] = 'a';
$b[] = 'b';
$b[] = 'c';
// After the above code is executed, $a will be the array
// array('color' => 'red', 'taste' => 'sweet', 'shape' => 'round',
// 'name' => 'apple', 0 => 4), and $b will be the array
// array(0 => 'a', 1 => 'b', 2 => 'c'), or simply array('a', 'b', 'c').
?>
Example #1 Using array()
<?php
// Array as (property-)map
$map = array( 'version' => 4,
'OS' => 'Linux',
'lang' => 'english',
'short_tags' => true
);
// strictly numerical keys
$array = array( 7,
8,
0,
156,
-10
);
// this is the same as array(0 => 7, 1 => 8, ...)
$switching = array( 10, // key = 0
5 => 6,
3 => 7,
'a' => 4,
11, // key = 6 (maximum of integer-indices was 5)
'8' => 2, // key = 8 (integer!)
'02' => 77, // key = '02'
0 => 12 // the value 10 will be overwritten by 12
);
// empty array
$empty = array();
?>
Example #2 集合
<?php
$colors = array('red', 'blue', 'green', 'yellow');
foreach ($colors as $color) {
echo "Do you like $color?\n";
}
?>
以上常式會輸出:
Do you like red?
Do you like blue?
Do you like green?
Do you like yellow?
直接改變數組的值在 PHP 5 中可以通過引用傳遞來做到。之前的版本需要需要採取變通的方法:
Example #3 集合
<?php
// PHP 5
foreach ($colors as &$color) {
$color = strtoupper($color);
}
unset($color); /* ensure that following writes to
$color will not modify the last array element */
// Workaround for older versions
foreach ($colors as $key => $color) {
$colors[$key] = strtoupper($color);
}
print_r($colors);
?>
以上常式會輸出:
Array
(
[0] => RED
[1] => BLUE
[2] => GREEN
[3] => YELLOW
)
本例生成一個下標從1開始的數組。This example creates a one-based array.
Example #4 下標從1開始的數組
<?php
$firstquarter = array(1 => 'January', 'February', 'March');
print_r($firstquarter);
?>
以上常式會輸出:
Array
(
[1] => 'January'
[2] => 'February'
[3] => 'March'
)
Example #5 填充數組
<?php
// fill an array with all items from a directory
$handle = opendir('.');
while (false !== ($file = readdir($handle))) {
$files[] = $file;
}
closedir($handle);
?>
數組是有序的。也可以使用不同的排序函數來改變順序。更多信息參見數組函數。可以用 count() 函數來數出數組中元素的個數。
Example #6 數組排序
<?php
sort($files);
print_r($files);
?>
因為數組中的值可以為任意值,也可是另一個數組。這樣可以產生遞歸或多維數組。
Example #7 遞歸和多維數組
<?php
$fruits = array ( "fruits" => array ( "a" => "orange",
"b" => "banana",
"c" => "apple"
),
"numbers" => array ( 1,
2,
3,
4,
5,
6
),
"holes" => array ( "first",
5 => "second",
"third"
)
);
// Some examples to address values in the array above
echo $fruits["holes"][5]; // prints "second"
echo $fruits["fruits"]["a"]; // prints "orange"
unset($fruits["holes"][0]); // remove "first"
// Create a new multi-dimensional array
$juices["apple"]["green"] = "good";
?>
數組(Array) 的賦值總是會涉及到值的拷貝。使用 引用操作符 通過引用來拷貝數組。
<?php
$arr1 = array(2, 3);
$arr2 = $arr1;
$arr2[] = 4; // $arr2 is changed,
// $arr1 is still array(2, 3)
$arr3 = &$arr1;
$arr3[] = 4; // now $arr1 and $arr3 are the same
?>
『伍』 php如何驗證網址是否正確
public function getUrlParams()
{
if ($this->_urlParams === null)
{
$pa = @parse_url($this->getUrl());
$pa['scheme'] = isset($pa['scheme']) ? strtolower($pa['scheme']) : 'http';
if ($pa['scheme'] !== 'http' && $pa['scheme'] !== 'https')
{
trigger_error("Invalid url scheme `{$pa['scheme']}`", E_USER_WARNING);
return false;
}
if (!isset($pa['host']))
{
trigger_error("Invalid request url, host required", E_USER_WARNING);
return false;
}
if (!isset($pa['path']))
$pa['path'] = '/';
// basic auth
if (isset($pa['user']) && isset($pa['pass']))
$this->applyBasicAuth($pa['user'], $pa['pass']);
// convert host to IP address
$port = isset($pa['port']) ? intval($pa['port']) : ($pa['scheme'] === 'https' ? 443 : 80);
$pa['ip'] = $this->hasHeader('x-server-ip') ?
$this->getHeader('x-server-ip') : self::getIpAddr($pa['host']);
$pa['conn'] = ($pa['scheme'] === 'https' ? 'ssl' : 'tcp') . '://' . $pa['ip'] . ':' . $port;
// host header
if (!$this->hasHeader('host'))
$this->setHeader('host', strtolower($pa['host']));
else
$pa['host'] = $this->getHeader('host');
$this->_urlParams = $pa;
}
return $this->_urlParams;
}
public function getUrlParam($key)
{
$pa = $this->getUrlParams();
return isset($pa[$key]) ? $pa[$key] : null;
}
『陸』 python3和Python2的區別
具體區別如下
1:列印時,py2需要可以不需要加括弧,py3 需要python 2 :print ('lili') , print 'lili'python 3 : print ('lili') python3 必須加括弧exec語句被python3廢棄,統一使用exec函數
2:內涵
Python2:1,臃腫,源碼的重復量很多。 2,語法不清晰,摻雜著C,php,Java的一些陋習。
Python3:幾乎是重構後的源碼,規范,清晰,優美。
3: 輸出中文的區別python2:要輸出中文 需加 # -*- encoding:utf-8 -*-Python3 :直接輸出
4:input不同python2 :raw_input python3 :input 統一使用input函數
5:指定位元組python2在編譯安裝時,可以通過參數-----enable-unicode=ucs2 或-----enable-unicode=ucs4分別用於指定使用2個位元組、4個位元組表示一個unicode;python3無法進行選擇,默認使用 ucs4查看當前python中表示unicode字元串時佔用的空間:impor sysprint(sys.maxunicode)#如果值是65535,則表示使用usc2標准,即:2個位元組表示#如果值是1114111,則表示使用usc4標准,即:4個位元組表示
6:py2:xrangerangepy3:range 統一使用range,Python3中range的機制也進行修改並提高了大數據集生成效率
7:在包的知識點里包:一群模塊文件的集合 + __init__區別:py2 : 必須有__init__py3:不是必須的了
8:不相等操作符"<>"被Python3廢棄,統一使用"!="
9:long整數類型被Python3廢棄,統一使用int
10:迭代器iterator的next()函數被Python3廢棄,統一使用next(iterator)
11:異常StandardError 被Python3廢棄,統一使用Exception
12:字典變數的has_key函數被Python廢棄,統一使用in關鍵詞
13:file函數被Python3廢棄,統一使用open來處理文件,可以通過io.IOBase檢查文件類型
『柒』 php有沒有什麼函數可以獲取一個方法中的參數名和參數類型的
/**
*獲取一個函數的依賴
*@paramstring|callable$func
*@paramarray$param調用方法時所需參數形參名就是key值
*@returnarray返回方法調用所需依賴
*/
functiongetFucntionParameter($func,$param=[]){
if(!is_array($param)){
$param=[$param];
}
$ReflectionFunc=newReflectionFunction($func);
$depend=array();
foreach($ReflectionFunc->getParameters()as$value){
if(isset($param[$value->name])){
$depend[]=$param[$value->name];
}elseif($value->isDefaultValueAvailable()){
$depend[]=$value->getDefaultValue();
}else{
$tmp=$value->getClass();
if(is_null($tmp)){
thrownewException("{$class}");
}
$depend[]=$this->get($tmp->getName());
}
}
return$depend;
}
functiontest($a,$b=20){
echo$a,',',$b;
}
$depend=getFucntionParameter('test',['a'=>30,'b'=>40]);
call_user_func_array('test',$depend);//30,40
上面的函數是我開發的框架的容器的方法。
php提供了很完整的反射機制。不但可以反射函數,還可以反射方法,反射類構造函數。