WebDev 字符编码
2013-02-02
Content-Type: text/html; charset=ISO-8859-4
HTTP 头部
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- HTML5:
<meta charset="utf-8">
<?xml version="1.0" encoding="ISO-8859-1"?>
XHTML 可以才用 XML 声明来定义编码
b2a
2012-03-07
按二进制位来算:
- Base16 四位
- Base32 五位
- Base64 六位
不按二进制位来算:
- Base36 数字 + 字母
- Base62 数字 + 字母(大小写敏感)
- Base58 数字 + 字母(大小写敏感),然后排除
0OIi
4 个字符
- Base85 有多种方案
b2a
2012-03-07
b2a
2012-03-07
b2a
2012-03-07
PHP
2011-12-07
遇到函数声明时前面加引用符号的情况。
调用函数时加引用符号可以理解,就是声明的接受变量是一个引用嘛。(实验证明,这是错的,说引用类型只能赋值给变量。What?不知所云,求指教。)
可是函数声明就没有那么好理解了。
php.net 中的例子:
<?php
class foo {
public $value = 42;
public function &getValue() {
return $this->value;
}
}
$obj = new foo;
$myValue = &$obj->getValue(); // $myValue is a reference to $obj->value, which is 42.
$obj->value = 2;
echo $myValue; // prints the new value of $obj->value, i.e. 2.
?>
本例中 getValue
函数所返回的对象的属性将被赋值,而不是拷贝,就和没有用引用语法一样。
还是没太明白,试验先。
eg 1、普通的函数声明,然后引用接收。
function foo() {
$var = 0;
return $var;
}
$get = & foo();
var_dump($get);
$get = 5;
$get = & foo();
var_dump($get);
结果:
Strict standards: Only variables should be assigned by reference
int 0
Strict standards: Only variables should be assigned by reference
int 0
eg 2、将上面例子中的函数声明成了引用返回。
function & foo() {
$var = 0;
return $var;
}
$get = foo();
var_dump($get);
$get = 5;
$get = foo();
var_dump($get);
结果:
int 0
int 0
和没有把函数声明成引用一样的效果。
eg 3、将上面例子中的函数声明成了引用返回。
function & foo() {
static $var = 0;
return $var;
}
$get = & foo();
var_dump($get);
$get = 5;
$get = & foo();
var_dump($get);
结果:
int 0
int 5
eg 4、面向对象中引用返回的应用。
/**
* 试验辅类,用于试验主类属性 ref 的 `->` 操作。
*/
class Ex {
public $some;
function __construct() {
$this->some = 0;
}
public function set($v) {
$this->some = $v;
}
public function get() {
return $this->some;
}
}
/**
* 试验主类
*/
class MyClass {
public $ref;
function __construct() {
$this->ref = & foo();
}
}
function & foo() {
$var = new Ex;
return $var;
}
$class = new MyClass();
$class->ref->set(5);
var_dump($class->ref->get());
结果:
int 5
总结
- 一般来说,函数返回就是返回一个值。
- 引用就是计算出变量的地址。
- 引用返回是把返回变量的引用返回来了。而且,返回引用的格式决定了两边都要用
&
声明。
若只是在函数那边声明引用,那么返回结果将依然是赋值给接收变量。是不是就是返回一个变量拷贝呢?
若只是在接收变量那边声明引用就会报错,因为函数(还是返回的值?)不能用 &
求地址。
PHP
2011-11-10
魔术常量
https://php.net/manual/zh/language.constants.predefined.php
__LINE__
文件中的当前行号。
__FILE__
文件的完整路径和文件名。如果用在被包含文件中,则返回被包含的文件名。
__DIR__
文件所在的目录。如果用在被包括文件中,则返回被包括的文件所在的目录。它等价于 dirname(FILE)。除非是根目录,否则目录中名不包括末尾的斜杠。(PHP 5.3.0中新增)
__FUNCTION__
函数名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该函数被定义时的名字(区分大小写)。
__CLASS__
类的名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该类被定义时的名字(区分大小写)。
__METHOD__
类的方法名(PHP 5.0.0 新加)。返回该方法被定义时的名字(区分大小写)。
__NAMESPACE__
当前命名空间的名称(大小写敏感)。这个常量是在编译时定义的(PHP 5.3.0 新增)
魔术方法
https://php.net/manual/zh/language.oop5.magic.php
约十三个有特殊含义的方法:
__construct()
、 __destruct()
、 __call()
、 __callStatic()
、 __get()
、
__set()
、 __isset()
、 __unset()
、 __sleep()
、 __wakeup()
、 __toString()
、
__invoke()
、 __set_state()
、 __clone()
这些方法在PHP中被称为"魔术方法"(Magic methods)。 你在命名自己的类方法时不能使用这些方法名, 除非你希望使用"魔术"功能。
构造函数和析构函数
如果你想明确地销毁一个对象,你可以给指向该对象的变量分配任何其它值.通常将变量赋值勤为NULL或者调用unset。
属性重载
public void __set ( string $name , mixed $value )
在给未定义的变量赋值时调用。
public mixed __get ( string $name )
读取未定义的变量的值时调用。
public bool __isset ( string $name )
当对未定义的变量调用 isset()
或 empty()
时调用。
public void __unset ( string $name )
当对未定义的变量调用 unset()
时调用。
参数 $name
是指要操作的变量名称 ,包括没有访问权限的属性(protected,private)。__set()
方法的 $value
参数指定了 $name
变量的值。
属性重载只能在对象中进行。在静态方法中,这些魔术方法将不会被调用。所以这些方法都不能被 声明为static。 从PHP 5.3.0起, 将这些魔术方法定义为static会产生一个警告。
方法重载
public mixed __call ( string $name , array $arguments )
当调用一个不可访问方法(如未定义,或者不可见)时调用 。
public static mixed __callStatic ( string $name , array $arguments )
当在静态方法中调用一个不可访问方法(如未定义,或者不可见)时调用。
$name
参数是要调用的方法名称。
$arguments
参数是一个数组,包含着要传递给方法的参数。
__sleep()
和 __wakeup()
public array __sleep ( void )
函数会检查是否存在一个魔术方法 __sleep()
.
如果存在,__sleep()
方法会先被调用,然后才执行序列化操作。
这个功能可以用于清理对象,并返回一个包含对象中所有应被序列化的变量名称的数组。
如果该方法不返回任何内容,则 NULL 被序列化,并产生一个 E_NOTICE
错误。
__sleep()
方法常用于提交未提交的数据,或类似的清理操作。同时,如果你有一些很大的对象, 不需要全部保存,这个功能就很好用。
void __wakeup ( void )serialize()
与之相反,unserialize()
会检查是否存在一个 __wakeup()
方法。如果存在,则会先调用 __wakeup
方法,预先准备对象需要的资源。
__wakeup()
经常用在反序列化操作中,例如重新建立数据库连接,或执行其它初始化操作。
对象的输出
public string __toString ( void )
当对象被当做字符串输出时这个函数会被调用,该方法必须返回一个字符串,否则产生一个 E_RECOVERABLE_ERROR
致命错误。
mixed __invoke ([ $... ] )
当尝试以调用函数的方式调用一个对象时,__invoke()
方法会被自动调用。
static object __set_state ( array $properties )
当调用 var_export()
时,这个静态方法会被调用(自PHP 5.1.0起有效)。
本方法的唯一参数是一个数组,其中包含按 array('property' => value, ...)
格式排列的类属性。
对象复制
在多数情况下,我们并不需要完全复制一个对象来获得其中属性。但有一个情况下确实需要:如果你有一个 GTK窗口对象,该对象持有窗口相关的资源。你可能会想复制一个新的窗口,保持所有属性与原来的窗口相同, 但必须是一个新的对象(因为如果不是新的对象,那么一个窗口中的改变就会影响到另一个窗口)。还有一种情况: 如果对象A中保存着对象B的引用,当你复制对象A时,你想其中使用的对象不再是对象B而是B的一个副本,那么 你必须得到对象A的一个副本。
对象复制可以通过clone关键字来完成(如果可能,这将调用对象的 __clone()
方法)。对象中的 __clone()
方法不能被直接调用。
$copy_of_object = clone $object;
当对象被复制后,PHP5会对对象的所有属性执行一个浅复制(shallow copy)。所有的引用属性 仍然会是一个指向原来的变量的引用。
void __clone ( void )
当复制完成时, 如果定义了 __clone()
方法, 则新创建的对象(复制生成的对象)中的 __clone()
方法会被调用, 可用于修改属性的值(如果有必要的话)。
自动加载对象
很多开发者写面向对象的应用程序时对每个类的定义建立一个 PHP 源文件。一个很大的烦恼是不得不在每个脚本(每个类一个文件)开头写一个长长的包含文件列表。在 PHP 5 中,不再需要这样了。可以定义一个 __autoload
函数,它会在试图使用尚未被定义的类时自动调用。通过调用此函数,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类。
Note:在 __autoload
函数中抛出的异常不能被 catch 语句块捕获并导致致命错误,而且如果使用 PHP 的 CLI 交互模式 时,Autoloading 不存在。
魔术引号(废弃)
魔术引号(Magic Quote)是一个自动将进入 PHP 脚本的数据进行转义的过程。最好在编码时不要转义而在运行时根据需要而转义。 magic_quotes_gpc 影响到 HTTP 请求数据(GET
,POST
和 COOKIE
)。不能在运行时改变。在 PHP 中默认值为 on。
magic_quotes_runtime
如果打开的话,大部份从外部来源取得数据并返回的函数,包括从数据库和文本文件,所返回的数据都会被反斜线转义。
该选项可在运行的时改变,在 PHP 中的默认值为 off。
magic_guotes_sybase
如果打开的话,将会使用单引号对单引号进行转义而非反斜线。
此选项会完全覆盖 magic_quotes_gpc
。如果同时打开两个选项的话,单引号将会被转义成 ''。而双引号、反斜线 和 NULL 字符将不会进行转义。
__autoload
如果要定义一个全局的自动加载类,则必须用 spl_autoload_register()
方法将处理类注册到PHP标准库:
<?php
class Loader {
static function autoload_class($class_name) {
//寻找正确的$class_name类,并引入,没有则抛出异常
}
}
/**
* 设置对象的自动载入
* spl`_autoload_register — Register given function as __autoload()` implementation
*/
spl_autoload_register(array('Loader', 'autoload_class'));
$a = new Test();//Test没用require就实例化,实现自动加载,很多框架就用这种方法自动加载类
?>
注意: 在 __autoload
函数中抛出的异常不能被 catch 语句块捕获并导致致命错误,所以应该在函数本身做捕获。
PHP
2011-05-03
// 创建目录
if (!is_dir("mydirectory")) {
mkdir("mydirectory");
} else {
die("目录已存在");
}
// 创建多级目录
mkdir("path/to/my/directory", 0777, true);
// 删除目录
rmdir("newdir");
// 打开目录
$dir = opendir(".");
// 读目录
while($file = readdir($dir)) {
echo $file . "<br />";
}
// 读目录 2
$directory = '/path/to/dir';
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($directory,
RecursiveDirectoryIterator::SKIP_DOTS), // 忽略 . / ..
RecursiveIteratorIterator::SELF_FIRST); // 深度优先
foreach ($iterator as $item) {
if ($item->isDir()) {
echo "目录: " . $item->getPath() . "\n";
} else {
echo "文件: " . $item->getPathname() . "\n";
}
}
// 关闭目录
closedir($dir);
// 打开文件
$myfile = fopen("example.txt", "r");
// 读文件
$data = fread($myfile, filesize("example.txt"));
// 写文件
fwrite($myfile, "This is some text");
fclose($myfile);
// 读文件
$data = file_get_contents("example.txt");
// 写文件
file_put_contents("example.txt", "This is some text");
// 删除文件
unlink("example.txt");
PHP
2011-05-02
date
/time
/strtotime
time() # 获得当前时间戳
date(fmtStr, timestamp)
strtotime("+1 day")
strtotime("next Thursday")
strtotime("last Thursday")
# 字符串 => 时间戳
php -r 'var_dump(strtotime("today"));' # 零点
php -r 'var_dump(strtotime("2011"));'
php -r 'var_dump(strtotime("2011-12"));'
php -r 'var_dump(strtotime("2011-12-13"));'
php -r 'var_dump(strtotime("2011-12-13 06:00:00"));'
# 时间戳 => 字符串
php -r 'var_dump(date("Y-m-d H:i:s", 0));'
DateTime
DateTimeInterface
DateTime
DateTimeImmutable
DateTimeZone
DateInterval
DatePeriod
实现 Traversable
接口
// DateTimeInterface::ATOM = "Y-m-d\TH:i:sP";
// DateTimeInterface::COOKIE = "l, d-M-Y H:i:s T";
// DateTimeInterface::ISO8601 = "Y-m-d\TH:i:sO";
// DateTimeInterface::RFC822 = "D, d M y H:i:s O";
// DateTimeInterface::RFC850 = "l, d-M-y H:i:s T";
// DateTimeInterface::RFC1036 = "D, d M y H:i:s O";
// DateTimeInterface::RFC1123 = "D, d M Y H:i:s O";
// DateTimeInterface::RFC7231 = "D, d M Y H:i:s \G\M\T";
// DateTimeInterface::RFC2822 = "D, d M Y H:i:s O";
// DateTimeInterface::RFC3339 = "Y-m-d\TH:i:sP";
// DateTimeInterface::RFC3339_EXTENDED = "Y-m-d\TH:i:s.vP";
// DateTimeInterface::RSS = "D, d M Y H:i:s O";
// DateTimeInterface::W3C = "Y-m-d\TH:i:sP";
$dateTime = new DateTime();
foreach ([
'ATOM',
'COOKIE',
'ISO8601',
'RFC822',
'RFC850',
'RFC1036',
'RFC1123',
'RFC2822',
'RFC3339',
'RFC3339_EXTENDED',
'RSS',
'W3C',
] as $format) {
eval("print 'DateTimeInterface::$format\t'.\$dateTime->format(DateTimeInterface::$format).\"\n\";");
}
-
public static createFromFormat(string $format, string $datetime, ?DateTimeZone $timezone = null): DateTime|false
-
public format(string $format): string
-
public modify(string $modifier): DateTime|false
public add(DateInterval $interval): DateTime
-
public sub(DateInterval $interval): DateTime
-
public diff(DateTimeInterface $targetObject, bool $absolute = false): DateInterval
-
public getOffset(): int
public getTimestamp(): int
public setTimestamp(int $timestamp): DateTime
public getTimezone(): DateTimeZone|false
public setTimezone(DateTimeZone $timezone): DateTime
public setDate(int $year, int $month, int $day): DateTime
public setISODate(int $year, int $week, int $dayOfWeek = 1): DateTime
public setTime(int $hour, int $minute, int $second = 0, int $microsecond = 0): DateTime
$d = new DateTime('2011-01-01T15:03:01.012345Z');
echo $d->format('Y-m-d\TH:i:s.u'); // 2011-01-01T15:03:01.012345
$d->modify('+1 month');
$d->add(new DateInterval("P1M"));
$publishDate = DateTime::createFromFormat('m/d/Y', '1/10/2014');
echo $publishDate->getTimestamp();
PHP
2011-05-01
- 单引号,双引号
- heredoc
<<<EOF ... EOF;
- nowdoc
<<<'EOF' ... EOF;
忽略变量和转义
操作
- 字符串连接
$s1 . $s2
- echo
- print
int printf ( string $format , mixed ...$args )
string sprintf ( string $format , mixed ...$args )
void var_dump ( mixed $expression , mixed ...$expressions )
mixed print_r ( mixed $expression [, bool $return = false ] )
strlen(string $string): int
substr(string $string, int $start, ?int $length = null): string|false
str_replace(string|array $search, string|array $replace, string|array $subject, ?int &$count = null): string|array|null
strpos(string $haystack, string $needle, ?int $offset = 0): int|false
explode(string $delimiter, string $string, ?int $limit = PHP_INT_MAX): array
implode(string $glue, array $pieces): string
strtolower(string $string): string
strtoupper(string $string): string
ucfirst(string $string): string
ucwords(string $string, string|null $delimiters = " \t\r\n\f\v"): string
trim(string $string, ?string $charlist = " \t\n\r\0\x0B"): string
str_repeat(string $string, int $multiplier): string
htmlspecialchars(string $string, int $flags = ENT_COMPAT | ENT_HTML401, ?string $encoding = ini_get("default_charset"), bool $double_encode = true): string
strtolower(string $string): string
strtoupper(string $string): string
lcfirst(string $string): string
strrev(string $string): string
ucfirst(string $string): string
ucwords(string $string): string
str_pad(string $string, int $length, string $pad_string = " ", int $pad_type = STR_PAD_RIGHT): string
strcmp(string $str1, string $str2): int
strcasecmp(string $str1, string $str2): int
stristr(string $haystack, string $needle, bool $before_needle = false): string|false
strstr(string $haystack, string $needle, bool $before_needle = false): string|false
strtok(string $string, string $delimiter): string|false
strpos(string $haystack, string $needle, ?int $offset = 0): int|false
strrpos(string $haystack, string $needle, ?int $offset = 0): int|false
substr_count(string $haystack, string $needle, ?int $offset = 0, ?int $length = null): int
substr_replace(string $string, string $replacement, int|array $start, ?int|array $length = null): string|array
wordwrap(string $string, ?int $width = 75, ?string $break = "\n", bool $cut = false): string
str_shuffle(string $string): string
str_split(string $string, int $split_length = 1): array
str_word_count(string $string, ?int $format = 0, ?string $charlist = ""): int|array
strcoll(string $str1, string $str2): int
strcspn(string $string, string $mask, ?int $start = 0, ?int $length = null): int
strip_tags(string $string, ?string $allowable_tags = null): string
html_entity_decode(string $string, ?int $flags = ENT_COMPAT | ENT_HTML401, ?string $encoding = ini_get("default_charset")): string
htmlentities(string $string, int $flags = ENT_COMPAT | ENT_HTML401, ?string $encoding = ini_get("default_charset"), bool $double_encode = true): string
htmlspecialchars_decode(string $string, ?int $flags = ENT_COMPAT | ENT_HTML401): string
preg_match(string $pattern, string $subject, ?array &$matches = null, ?int $flags = 0, int $offset = 0): int|false
preg_replace(mixed $pattern, mixed $replacement, mixed $subject, ?int $limit = -1, ?int &$count = null): mixed
preg_split(string $pattern, string $subject, ?int $limit = -1, ?int $flags = 0): array
substr_compare(string $main_str, string $str, int $offset, ?int $length = null, bool $case_insensitive = false): int
strcoll(string $str1, string $str2): int
strcspn(string $string, string $mask, ?int $start = 0, ?int $length = null): int
strip_tags(string $string, ?string $allowable_tags = null): string
strtr(string $string, string|array $replace_pairs): string
strval(mixed $var): string
substr_replace(string $string, string $replacement, int|array $start, ?int|array $length = null): string|array
levenshtein(string $str1, string $str2, ?int $cost_ins = 1, ?int $cost_rep = 1, ?int $cost_del = 1): int