php基础知识

基本介绍

php标记 <?php ?>

如果文件内容是纯 PHP 代码,在文件末尾删除 PHP 结束标记。可以避免在 PHP 结束标记之后意外加入了空格或换行符,会导致 PHP 开始输出这些空白,而脚本中此时并无输出的意图

<?php
echo "Hello world";
echo "Last statement";
// 脚本至此结束,并无 PHP 结束标记
  • php作为纯脚本代码运行

  • php作为CGI执行

php嵌入到html中执行

index.html文件

<html>
<head>
  <meta charset="utf-8">
</head>
<body>
<?php if ($expression == true): ?>
  This will show if the expression is true.
<?php else: ?>
  Otherwise this will show.
<?php endif; ?>
</body>
</html>

index.php 文件

<?php
$expression = true;
include(relpath('./').'/index.html');

数据类型

PHP 支持 8 种原始数据类型。

  1. 四种标量类型:
    • boolean(布尔型)
    • integer(整型)
    • float(浮点型,也称作 double)
    • string(字符串)
  2. 两种复合类型:
    • array(数组)
    • object(对象)
  3. 两种特殊类型
    • resource(资源)
    • null(无类型)
<?php

// 字符串连接
$num = 12.8;
$string = "this is world".$num;

// 双引号中使用变量
$world = "world";
$hello = "hello {$world}";

// 转义特殊字符
$class_name = "\\name";
echo $class_name;

// 数组
$array = array(
    "foo" => "bar",
    "bar" => "foo",
    100   => -100,
    -100  => 100,
);
var_dump($array['foo']);
unset ($array[100]);
$array["x"] = 42;


// 没有键名的索引数组
$array = array("foo", "bar", "hallo", "world");
var_dump($array);

// 遍历
foreach ($array as $key => $value) {
  var_dump($key, $value);
}

// 对象
class foo
{
    function do_foo()
    {
        echo "Doing foo.";
    }
}

$bar = new foo;
$bar->do_foo();

?>
  • gettype()函数可以得到变量的类型
  • is_[type]()函数可以用来判断某个变量是否某个类型
  • var_dump()函数会输出变量的类型和值

php中的false

必要时可以调用boolean()函数来实现转换,当转换为 boolean 时,以下值被认为是 FALSE:

  • 布尔值 FALSE 本身
  • 整型值 0(零)
  • 浮点型值 0.0(零)
  • 空字符串,以及字符串 “0”
  • 不包括任何元素的数组
  • 不包括任何成员变量的对象(仅 PHP 4.0 适用)
  • 特殊类型 NULL(包括尚未赋值的变量)
  • 从空标记生成的 SimpleXML 对象
  • 除以上情况,其他均为true

PHP 中没有整除的运算符。1/2 产生出 float 0.5。值可以舍弃小数部分强制转换为 integer,或者使用 round() 函数可以更好地进行四舍五入

要使用八进制表达,数字前必须加上 0(零)。要使用十六进制表达,数字前必须加上 0x。要使用二进制表达,数字前必须加上 0b

一个字符串 string 就是由一系列的字符组成,其中每个字符等同于一个字节。这意味着 PHP 只能支持 256 的字符集,因此不支持 Unicode

Resource 资源类型 资源 resource 是一种特殊变量,保存了到外部资源的一个引用 ,可以用 is_resource()函数测定一个变量是否是资源,函数 get_resource_type()则返回该资源的类型。

NULL值表示一个变量没有值。NULL 类型唯一可能的值就是 NULL。在下列情况下一个变量被认为是 NULL: 1.被赋值为 NULL 2.尚未被赋值 3.被 unset()。

一些函数如 call_user_func() 或 usort() 可以接受用户自定义的回调函数作为参数。回调函数不止可以是简单函数,还可以是对象的方法,包括静态类方法。

变量

预定义变量

php变量作用域

php 中在函数内部不能访问外部变量,可以输出$GLOBALS查看详情

php 中全局变量在函数中使用时必须声明为 global

<?php
$a = 1;
$b = 2;

function Sum()
{
    global $a, $b;
    $b = $a + $b;
}

Sum();
echo $b;

使用静态变量

<?php
function fac($number)
{
  static $sum = 0;
  echo $sum . "\n";

  if ($number == 0) {
    $sum += $number;
    return 1;
  } else {
    $sum += $number;
    return $number * fac($number - 1);
  }
}
echo fac(4);

常量

<?php

// 合法的常量名
define("FOO",     "something");
define("FOO2",    "something else");
define("FOO_BAR", "something more");

// 非法的常量名
define("2FOO",    "something");

// 下面的定义是合法的,但应该避免这样做:(自定义常量不要以__开头)
// 也许将来有一天PHP会定义一个__FOO__的魔术常量
// 这样就会与你的代码相冲突
define("__FOO__", "something");

PHP 向它运行的任何脚本提供了大量的预定义常量。不过很多常量都是由不同的扩展库定义的,只有在加载了这些扩展库时才会出现,或者动态加载后,或者在编译时已经包括进去了

预定义常量

<?php
class System {
  const OS_UNKNOWN = 1;
  const OS_WIN = 2;
  const OS_LINUX = 3;
  const OS_OSX = 4;

  /**
   * @return int
   */
  static public function getOS() {
    switch (true) {
      case stristr(PHP_OS, 'DAR'): return self::OS_OSX;
      case stristr(PHP_OS, 'WIN'): return self::OS_WIN;
      case stristr(PHP_OS, 'LINUX'): return self::OS_LINUX;
      default : return self::OS_UNKNOWN;
    }
  }
}

常用的魔术常量

__DIR__ __FILE__ __METHOD__ __NAMESPACE__

表达式

任何有值的东西

运算符

正常的运算符 常用的包括3元表达式

流程控制

  • if
  • else
  • elseif
  • 流程控制的替代语法

    PHP 提供了一些流程控制的替代语法,包括 if,while,for,foreach 和 switch。替代语法的基本形式是把左花括号({)换成冒号(:),把右花括号(})分别换成 endif;,endwhile;,endfor;,endforeach; 以及 endswitch;通常在html页面中使用

    <body>
      <?php if ($a == 5): ?>
      A is equal to 5
      <?php endif; ?>
    </body>
    
  • while
  • do-while
  • for
  • foreach

    在遍历中使用引用

    <?php
    $arr = array(1, 2, 3, 4);
    foreach ($arr as &$value) {
      $value = $value * 2;
    }
    // $arr 成为 (2, 4, 6, 8)
    unset($value); // 最后取消掉引用
    ?>
    
  • break
  • continue
  • switch
  • return
  • require

    require 和 include 几乎完全一样,除了处理失败的方式不同之外。require 在出错时产生 E_COMPILE_ERROR 级别的错误。换句话说将导致脚本中止而 include 只产生警告(E_WARNING),脚本会继续运行。

  • include
  • require_once

    require_once 语句和 require 语句完全相同,唯一区别是 PHP 会检查该文件是否已经被包含过,如果是则不会再次包含

  • include_once

函数

正常的函数使用

<?php
function foo($arg_1, $arg_2, /* ..., */ $arg_n)
{
    echo "Example function.\n";
    return $retval;
}

默认情况下,函数参数通过值传递(因而即使在函数内部改变参数的值,它并不会改变函数外部的值)。如果希望允许函数修改它的参数值,必须通过引用传递参数

<?php
function add_some_extra(&$string)
{
    $string .= 'and something extra.';
}
$str = 'This is a string, ';
add_some_extra($str);
echo $str;
?>

在函数中使用默认参数

<?php
function makecoffee($type = "cappuccino")
{
    return "Making a cup of $type.\n";
}
echo makecoffee();
echo makecoffee(null);
echo makecoffee("espresso");
?>

限制函数参数的类型

<?php
class C {}
class D extends C {}

// 并没有继承C
class E {}

function f(C $c) {
    echo get_class($c)."\n";
}

f(new C);
f(new D);
f(new E); // 这里会报错
?>

可变函数

PHP 支持可变函数的概念。这意味着如果一个变量名后有圆括号,PHP 将寻找与变量的值同名的函数,并且尝试执行它。可变函数可以用来实现包括回调函数,函数表在内的一些用途。

可变函数不能用于例如 echo(),print(),unset(),isset(),empty(),include(),require() 以及类似的语言结构。需要使用自己的包装函数来将这些结构用作可变函数。

<?php
$method = "action";
function action()
{
  echo "foo";
}
// 可变函数
$method();

内部(内置)函数

PHP 有很多标准的函数和结构。还有一些函数需要和特定地 PHP 扩展模块一起编译,否则在使用它们的时候就会得到一个致命的“未定义函数”错误。例如,要使用 image 函数中的 imagecreatetruecolor(),需要在编译 PHP 的时候加上 GD 的支持。或者,要使用 mysql_connect() 函数,就需要在编译 PHP 的时候加上 MySQL 支持。有很多核心函数已包含在每个版本的 PHP 中如字符串和变量函数。调用 phpinfo() 或者 get_loaded_extensions() 可以得知 PHP 加载了那些扩展库。同时还应该注意,很多扩展库默认就是有效的。

常用函数

isset() empty() unset() explode() sub_str() mb_sub_str() in_array() array_unique() str_replace()

类与对象

<?php
class simpleClass
{
  // public 代表可以在任何地方被访问
  public $var = 'a default value';

  // 类常量
  const pi = 3.1415926;

  // 任何地方可访问的一个方法
  public function displayVar()
  {
    //$this是一个到主对象的引用
    echo $this->var;
  }
}
// 利用new关键字生成一个对象
var simple = new simpleClass();

// 继承上一个类
class extendClass extends simplerClass
{
  function displayVar()
  {
    echo "Extending class\n";
    //调用父类中的方法
    parent::displayVar();
  }
}

自动加载类

<?php
class core
{
  public static function load()
  {
    // include
  }
}
spl_autoload_register('core::load');

// 调用了一个不存在的类 spl_autoload_register中指定的方法会被调用
// 类名 \core\lib\route 或作为参数传入core::load方法
new \core\lib\route();

构造函数

<?php
class core
{
  public $action =  'index';
  function __construct($action)
  {
    public $action = $action;
  }
}

<?php
class route extends core
{
  function __construct()
  {
    // 调用父类的构造函数
    parent::__construct();
  }
}

范围解析操作符号

范围解析操作符(也可称作 Paamayim Nekudotayim)或者更简单地说是一对冒号,可以用于访问静态成员,类常量,还可以用于覆盖类中的属性和方法。

<?php

// 在类外部使用
class MyClass {
  const CONST_VALUE = 'A constant value';
}

$classname = 'MyClass';
// 自 PHP 5.3.0 起
echo $classname::CONST_VALUE;

echo MyClass::CONST_VALUE;

// 在类内部使用
class OtherClass extends MyClass
{
  // static关键字是使用范围解析符的关键
  public static $my_static = 'static var';

  public static function doubleColon() {
    echo parent::CONST_VALUE . "\n";
    echo self::$my_static . "\n";
  }
}

$classname = 'OtherClass';
echo $classname::doubleColon(); // 自 PHP 5.3.0 起
OtherClass::doubleColon();

PHP 对待对象的方式与引用和句柄相同,即每个变量都持有对象的引用,而不是整个对象的拷贝。

属性声明是由关键字 public,protected 或者 private 开头,然后跟一个普通的变量声明来组成。属性中的变量可以初始化,但是初始化的值必须是常数,这里的常数是指 PHP 脚本在编译阶段时就可以得到其值,而不依赖于运行时的信息才能求值。 默认public

对属性或方法的访问控制,是通过在前面添加关键字 public(公有),protected(受保护)或 private(私有)来实现的。被定义为公有的类成员可以在任何地方被访问。被定义为受保护的类成员则可以被其自身以及其子类和父类访问。被定义为私有的类成员则只能被其定义所在的类访问

声明类属性或方法为静态,就可以不实例化类而直接访问。静态属性不能通过一个类已实例化的对象来访问(但静态方法可以)。 因为静态方法在一个命名空间里是唯一的

同样利用foreach遍历对象

命名空间

在PHP中,命名空间用来解决在编写类库或应用程序时创建可重用的代码如类或函数时碰到的两类问题:

  • 用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。
  • 为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性。
  • 一般以文件夹名字作为命名空间

/index.php

<?php
include(realpath('./').'/lib/core.php');
// 静态方法
\lib\core::load();

// 非静态方法
$o = new \lib\core();
$o->dump();

/lib/core.php

<?php
namespace lib;
class core
{
  public function dump()
  {
    //code
  }
  public static function load()
  {
    //code
  }
}

使用PDO连接数据库

php中内置了mysql API 和 升级版 mysqli 用来操作mysql但是不管是使用原生的MySQL API,还是MySQLi,都还是有缺陷的。

  1. 不支持事务机制;
  2. 仅支持MySQL,不能使用其它数据库。
  3. 不安全,可能有注入风险
  4. 不支持异常处理

PHP随后引入的PDO扩展巧妙的解决了这些问题

  • PDO使用dsn连接,支持众多类型的数据库,如mysql,postgresql,oracle,mssql等。
  • PDO(php data object)扩展类库为php访问数据库定义了轻量级的、一致性的接口,它提供了一个数据库访问抽象层。这样,无论你使用什么数据库,都可以通过一致的函数执行查询和获取数据。
  • PDO大大简化了数据库的操作并能够屏蔽不同数据库之间的差异,使用pdo可以很方便地进行跨数据库程序的开发,以及不同数据库间的移植,是将来php在数据库处理方面的主要发展方向。
<?php

$db = array(
  'dsn' => 'mysql:host=localhost;dbname=test;port=3306;charset=utf8',
  'host' => 'localhost',
  'port' => '3306',
  'dbname' => 'yarn',
  'username' => 'root',
  'password' => 'root',
  'charset' => 'utf8',
);

//连接
$options = array(
  //默认是PDO::ERRMODE_SILENT, 0, (忽略错误模式)
  PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
  // 默认是PDO::FETCH_BOTH, 4
  PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
);

try{
  $pdo = new PDO($db['dsn'], $db['username'], $db['password'], $options);
}catch(PDOException $e){
  die('数据库连接失败:' . $e->getMessage());
}

//或者更通用的设置属性方式:
//设置异常处理方式
//$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//设置默认关联索引遍历
//$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);

echo '<pre/>';

//1 查询

//1)使用query
//返回一个PDOStatement对象
$stmt = $pdo->query('select * from user limit 2');

//从结果集中获取下一行,用于while循环
//$row = $stmt->fetch();
//获取所有
$rows = $stmt->fetchAll();

$row_count = $stmt->rowCount();
//print_r($rows);

echo '<br>';

//2)使用prepare 推荐
$stmt = $pdo->prepare("select * from user where name = ? and age = ? ");
$stmt->bindValue(1,'test');
$stmt->bindValue(2,22);
//执行一条预处理语句 .成功时返回 TRUE, 失败时返回 FALSE
$stmt->execute();  
$rows = $stmt->fetchAll();
print_r($rows);



//2 新增、更新、删除
//1)普通操作
//$count  =  $pdo->exec("insert into user(name,gender,age)values('test',2,23)");
//echo $pdo->lastInsertId();

//$count  =  $pdo->exec("update user set name='test2' where id = 15");
//$count  =  $pdo->exec("delete from  user where id = 15");


//2)使用prepare 推荐!
/*
$stmt = $pdo->prepare("insert into user(name,gender,age)values(?,?,?)");
$stmt->bindValue(1, 'test');
$stmt->bindValue(2, 2);
$stmt->bindValue(3, 23);
$stmt->execute();
*/

//3)使用prepare 批量新增
$stmt = $pdo->prepare("insert into user(name,gender,age)values(?,?,?)");
$stmt->bindParam(1, $name);
$stmt->bindParam(2, $gender);
$stmt->bindParam(3, $age);

$data = array(
  array('t1', 1, 22),
  array('t2', 2, 23),
);

foreach ($data as $vo){
  list($name, $gender, $age) = $vo;
  $stmt->execute();
}

pdo事务

<?php
//开启事务处理
$pdo->beginTransaction();

try{
  //PDO预处理以及执行语句...
  $pdo->commit();
}catch(PDOException $e){
  $pdo->rollBack();

  //相关错误处理
  throw $e;
}
header("Location: http://example.com/myOtherPage.php");
header("Content-Type: text/json");
session_start();
$_SESSION;