利用PHP实现Hash表功能

 更新时间:2016年11月25日 14:57  点击:1797
Hash算法我们多少会了解一点了,下面来介绍利用php实现Hash表的一个例子,希望这些例子可以给各位带来帮助。

  Hash表作为最重要的数据结构之一,也叫做散列表。使用PHP实现Hash表的功能。PHP可以模拟实现Hash表的增删改查。通过对key的映射到数组中的一个位置来访问。映射函数叫做Hash函数,存放记录的数组称为Hash表。
Hash函数把任意长度的和类型的key转换成固定长度输出。不同的key可能拥有相同的hash。
Hash表的时间复杂度为O(1)

 代码如下 复制代码

<?php

class HashTable{
    private $arr = array();
    private $size = 10;
    public function __construct(){
        //SplFixedArray创建的数组比一般的Array()效率更高,因为更接近C的数组。创建时需要指定尺寸
        $this->arr = new SplFixedArray($this->size);
    }

    /**
     * Description: 简单hash算法。输入key,输出hash后的整数
     * @param $key
     * @return int
     */
    private function simpleHash($key){
        $len = strlen($key);
        //key中每个字符所对应的ASCII的值
        $asciiTotal = 0;
        for($i=0; $i<$len; $i++){
            $asciiTotal += ord($key[$i]);
        }
        return $asciiTotal % $this->size;
    }

    /**
     * Description: 赋值
     * @param $key
     * @param $value
     * @return bool
     */
    public function set($key, $value){
        $hash = $this->simpleHash($key);
        $this->arr[$hash] = $value;
        return true;
    }

    /**
     * Description: 取值
     * @param $key
     * @return mixed
     */
    public function get($key){
        $hash = $this->simpleHash($key);
        return $this->arr[$hash];
    }

    public function getList(){
        return $this->arr;
    }

    public function editSize($size){
        $this->size = $size;
        $this->arr->setSize($size);
    }
}
?>

下面对我们的HashTable进行测试。

 代码如下 复制代码

<?php
//测试1
$arr = new HashTable();
for($i=0; $i<15; $i++){
    $arr->set('key'.$i, 'value'.$i);
}
print_r($arr->getList());
//SplFixedArray Object
//(
//    [0] => value14
//    [1] => value4
//    [2] => value5
//    [3] => value6
//    [4] => value7
//    [5] => value8
//    [6] => value10
//    [7] => value11
//    [8] => value12
//    [9] => value13
//)
//不同的key可能产生相同的hash值,那么赋值的时候后操作会覆盖前操作。

//测试2
$arr->editSize(15);
for($i=0; $i<15; $i++){
    $arr->set('key'.$i, 'value'.$i);
}
print_r($arr->getList());
//SplFixedArray Object
//(
//    [0] => value14
//    [1] => value4
//    [2] => value0
//    [3] => value1
//    [4] => value2
//    [5] => value3
//    [6] => value10
//    [7] => value11
//    [8] => value12
//    [9] => value13
//    [10] => value14
//    [11] => value9
//    [12] =>
//    [13] =>
//    [14] =>
//)
?>

   

改变了值之后可以存放更多的元素。但是仍然存在不同的key可能产生相同的hash值,那么赋值的时候后操作会覆盖前操作的问题。这种冲突的问题我们来用拉链法解决。

    拉链法解决冲突。拉链法解决冲突的做法是将所有的相同Hash值的key放在一个链表中,比如key3和key14在hash之后都是0,那么在数组的键为0的地方存储这两个值,形式是链表。如果不能理解我的文字,请看下面的示例,看一下打印信息就明白了。拉链法是什么,就是链表。
    创建一个HashNode类,用来存储key和value的值,并且存储相同hash的另一个元素。在同一条链上,查找越后的元素越费时。时间复杂度为O(n).

 代码如下 复制代码

<?php
class HashNode{
    public $key;
    public $value;
    public $nextNode;
    public function __construct($key, $value, $nextNode=Null){
        $this->key = $key;
        $this->value = $value;
        $this->nextNode = $nextNode;
    }
}
class NewHashTable{
    private $arr;
    private $size = 10;
    public function __construct(){
        $this->arr = new SplFixedArray($this->size);
    }
    private function simpleHash($key){
        $asciiTotal = 0;
        $len = strlen($key);
        for($i=0; $i<$len; $i++){
            $asciiTotal += ord($key[$i]);
        }
        return $asciiTotal % $this->size;
    }
    public function set($key, $value){
        $hash = $this->simpleHash($key);
        if(isset($this->arr[$hash])){
            $newNode = new HashNode($key, $value, $this->arr[$hash]);
        }else{
            $newNode = new HashNode($key, $value, null);
        }
        $this->arr[$hash] = $newNode;
        return true;
    }
    public function get($key){
        $hash = $this->simpleHash($key);
        $current = $this->arr[$hash];
        while(!empty($current)){
            if($current->key == $key){
                return $current->value;
            }
            $current = $current->nextNode;
        }
        return NULL;
    }
    public function getList(){
        return $this->arr;
    }
}
?>

   

对我们新的HashTable进行测试

 代码如下 复制代码
<?php
//测试1
$newArr = new NewHashTable();
for($i=0; $i<30; $i++){
    $newArr->set('key'.$i, 'value'.$i);
}
print_r($newArr->getList());
var_dump($newArr->get('key3'));
//SplFixedArray Object
//(
//    [0] => HashNode Object
//(
//    [key] => key23
//            [value] => value23
//            [nextNode] => HashNode Object
//(
//    [key] => key14
//                    [value] => value14
//                    [nextNode] => HashNode Object
//(
//    [key] => key3
//                            [value] => value3
//                            [nextNode] =>
//                        )
//
//                )
//
//        )
//
//    [1] => HashNode Object
//(
//    [key] => key24
//            [value] => value24
//            [nextNode] => HashNode Object
//(
//    [key] => key15
//                    [value] => value15
//                    [nextNode] => HashNode Object
//(
//    [key] => key4
//                            [value] => value4
//                            [nextNode] =>
//                        )
//
//                )
//
//        )
//
//    [2] => HashNode Object
//(
//    [key] => key25
//            [value] => value25
//            [nextNode] => HashNode Object
//(
//    [key] => key16
//                    [value] => value16
//                    [nextNode] => HashNode Object
//(
//    [key] => key5
//                            [value] => value5
//                            [nextNode] =>
//                        )
//
//                )
//
//        )
//
//    [3] => HashNode Object
//(
//    [key] => key26
//            [value] => value26
//            [nextNode] => HashNode Object
//(
//    [key] => key17
//                    [value] => value17
//                    [nextNode] => HashNode Object
//(
//    [key] => key6
//                            [value] => value6
//                            [nextNode] =>
//                        )
//
//                )
//
//        )
//
//    [4] => HashNode Object
//(
//    [key] => key27
//            [value] => value27
//            [nextNode] => HashNode Object
//(
//    [key] => key18
//                    [value] => value18
//                    [nextNode] => HashNode Object
//(
//    [key] => key7
//                            [value] => value7
//                            [nextNode] =>
//                        )
//
//                )
//
//        )
//
//    [5] => HashNode Object
//(
//    [key] => key28
//            [value] => value28
//            [nextNode] => HashNode Object
//(
//    [key] => key19
//                    [value] => value19
//                    [nextNode] => HashNode Object
//(
//    [key] => key8
//                            [value] => value8
//                            [nextNode] =>
//                        )
//
//                )
//
//        )
//
//    [6] => HashNode Object
//(
//    [key] => key29
//            [value] => value29
//            [nextNode] => HashNode Object
//(
//    [key] => key10
//                    [value] => value10
//                    [nextNode] => HashNode Object
//(
//    [key] => key9
//                            [value] => value9
//                            [nextNode] =>
//                        )
//
//                )
//
//        )
//
//    [7] => HashNode Object
//(
//    [key] => key20
//            [value] => value20
//            [nextNode] => HashNode Object
//(
//    [key] => key11
//                    [value] => value11
//                    [nextNode] => HashNode Object
//(
//    [key] => key0
//                            [value] => value0
//                            [nextNode] =>
//                        )
//
//                )
//
//        )
//
//    [8] => HashNode Object
//(
//    [key] => key21
//            [value] => value21
//            [nextNode] => HashNode Object
//(
//    [key] => key12
//                    [value] => value12
//                    [nextNode] => HashNode Object
//(
//    [key] => key1
//                            [value] => value1
//                            [nextNode] =>
//                        )
//
//                )
//
//        )
//
//    [9] => HashNode Object
//(
//    [key] => key22
//            [value] => value22
//            [nextNode] => HashNode Object
//(
//    [key] => key13
//                    [value] => value13
//                    [nextNode] => HashNode Object
//(
//    [key] => key2
//                            [value] => value2
//                            [nextNode] =>
//                        )
//
//                )
//
//        )
//
//)
//string(6) "value3"
?>
在php中array_search和in_array函数都是用来查找数组中的值了,那么这们两他们的区别是什么呢?下面小编为各位介绍一下吧.

array_search和in_array都可以用来查找值是否存在与数组中,顾名思义,一个是搜寻数组,一个是判断是否在数组,array_search和in_array有什么区别呢?以及性能上有什么差异?

in_array用法

参数 描述
value 必需。规定要在数组搜索的值。
array 必需。规定要搜索的数组。
type 可选。如果设置该参数为 true,则检查搜索的数据与数组的值的类型是否相同。

array_search示例:


$array = array(0 => 'blue', 1 => 'red', 2 => 'green', 3 => 'red');
 
$key = array_search('green', $array); // $key = 2;
$key = array_search('red', $array);   // $key = 1;
第一个参数是要查找的值,第二个参数是数组,它返回的是查找到的值的“键”。而in_array只能判断是否存在,返回布尔值。在效率上in_array与array_search效率几乎相同,in_array仅返回真伪,array_search同时返回

array_search语法

参数 描述
value 必需。规定在数组中搜索的值。
array 必需。被搜索的数组。
strict

可选。可能的值:

  • true
  • false - 默认

如果值设置为 true,还将在数组中检查给定值的类型。(参见例子 2)

再如:

public function add_rewrite_tag( $tag, $regex, $query ) {
 $position = array_search( $tag, $this->rewritecode );
 if ( false !== $position && null !== $position ) {
  $this->rewritereplace[ $position ] = $regex;
  $this->queryreplace[ $position ] = $query;
 } else {
  $this->rewritecode[] = $tag;
  $this->rewritereplace[] = $regex;
  $this->queryreplace[] = $query;
 }
}

利用array_search返回位置,可以直接存放到需要标记位置的数组中。

下文为各位整理一个PHP的实现一个高效的数据库(文件存储,NOSQL)的例子,希望对各位有帮助。

 用文件的方式读写,一个文件是索引文件,另一个文件是真实的数据文件。
索引文件分为2部分,第一部分是所有的指针,记录第二部分的位置;第二部分是索引记录。所有的索引指针:是记录所有相同Hash值的key的指针,它是一个链表结构,记录在数据文件的位置和同key的下一个值。
索引记录中:每条记录有四部分,第一部分4个字节,是下一条索引的偏移量;第二部分是该记录的key,128字节;第三部分是数据偏移量,4个字节;第四部分是数据记录长度,4个字节。
我们设定文件的存储上限为262144个。

查找流程如下:

1、根据key算出hash值,获取该hash值的链表在索引文件的第一部分(所有指针区)的位置。
2、根据步骤一的位置,获取值,时间复杂度O(1);
2、根据步骤一中的值,找到索引文件中第二部分(索引记录)的位置,也就是和key相同hash值的所有指针的链表。顺着链表查找该key,获取该key在链表中存放的数据,数据只包含该key在索引文件中的位置,时间复杂度为O(n);
3、根据步骤二所获取的key在索引文件位置,得到索引文件中存放该key的信息。信息包含在真实数据文件中存放真实数据的位置。
4、根据步骤三所获取的位置,在真实数据文件中获取数据,并返回给应用程序。

测试结果:插入10000条耗时:793ms。查找10000条耗时:149ms。虽然这效率只有Redis的十分之一。。。但是请不要在意这些细节。。。

代码做了注释,上述文字有些乱。代码只实现三个方法,一个插入(如果存在则跳过),一个是查找,一个是删除。

思路来源:《PHP核心技术与最佳实践》一书。尊重作者,转载请保留该书名。

 代码如下 复制代码

<?php
//Hash表中的元素指针个数,每个指针都是int,存储hash链表的文件偏移量
define('DB_BUCKET_SIZE', 262144);
//每条记录的key的长度
define('DB_KEY_SIZE', 128);
//一条索引记录的长度
define('DB_INDEX_SIZE', DB_KEY_SIZE + 12);

//成功-返回码
define('DB_SUCCESS', 1);
//失败-返回码
define('DB_FAILURE', -1);
//key重复-返回码
define('DB_KEY_EXISTS', -2);

class DB{
    private $idx_fp;
    private $dat_fp;
    private $closed;

    /**
     * Description: 打开数据库
     * @param $pathName 数据文件的存放路径
     * @return mixed
     */
    public function open($pathName){
        $idx_path = $pathName . '.idx';
        $dat_path = $pathName . '.dat';
        if(!file_exists($idx_path)){
            $init = true;
            $mode = "w+b";
        }else{
            $init = false;
            $mode = 'r+b';
        }
        $this->idx_fp = fopen($idx_path, $mode);
        if(!$this->idx_fp){
            return DB_FAILURE;
        }
        if($init){
            //把0x00000000转换成无符号长整型的二进制
            $elem = pack('L', 0x00000000);
            for($i=0; $i< DB_BUCKET_SIZE; $i++){
                fwrite($this->idx_fp, $elem, 4);
            }
        }
        $this->dat_fp = fopen($dat_path, $mode);
        if(!$this->dat_fp){
            return DB_FAILURE;
        }

        return DB_SUCCESS;
    }

    /**
     * Description: Times33 Hash算法
     * @param $key
     * @return int
     */
    private function times33Hash($key){
        $len = 8;
        $key = substr(md5($key), 0, $len);
        $hash = 0;
        for($i=0; $i<$len; $i++){
            $hash += 33 * $hash + ord($key[$i]);
        }
        //0x7FFFFFFF:一个十六进制的数是4bit,8个就是32位,就是4字节,和一个int一样大。而F是1111,7是0111,那么这个十六进制的数就是头为0,其余为1的,首位是符号位,也就是说7fffffff是最大的整数。
        //& 0x7fffffff 可以保证返回的数是正整数
        return $hash & 0x7FFFFFFF;
    }

    /**
     * Description: 插入记录
     * @param $key
     * @param $value
     */
    public function add($key, $value){
        $offset = ($this->times33Hash($key) % DB_BUCKET_SIZE) * 4;

        $idxoff = fstat($this->idx_fp);
        $idxoff = intval($idxoff['size']);

        $datoff = fstat($this->dat_fp);
        $datoff = intval($datoff['size']);

        $keylen = strlen($key);
        $vallen = strlen($value);
        if($keylen > DB_KEY_SIZE){
            return DB_FAILURE;
        }
        //0表示这是最后一个记录,该链再无其他记录。
        $block = pack('L', 0x00000000);
        //键值
        $block .= $key;
        //如果键值的长度没有达到最大长度,则用0填充
        $space = DB_KEY_SIZE - $keylen;
        for($i=0; $i<$space; $i++){
            $block .= pack('C', 0x00);
        }
        //数据所在文件的偏移量
        $block .= pack('L', $datoff);
        //数据记录的长度
        $block .= pack('L', $vallen);
        //尽管SEEK_SET是默认值,但是显式声明了就不怕以后官方会改变了-.-
        fseek($this->idx_fp, $offset, SEEK_SET);
        //检测该key所对应的hash值是否存在了
        $pos = @unpack('L', fread($this->idx_fp, 4));
        $pos = $pos[1];
        //如果key不存在
        if($pos == 0){
            fseek($this->idx_fp, $offset, SEEK_SET);
            fwrite($this->idx_fp, pack('L', $idxoff), 4);

            fseek($this->idx_fp, 0, SEEK_END);
            fwrite($this->idx_fp, $block, DB_INDEX_SIZE);

            fseek($this->dat_fp, 0, SEEK_END);
            fwrite($this->dat_fp, $value, $vallen);

            return DB_SUCCESS;
        }
        //如果key存在
        $found = false;
        while($pos){
            fseek($this->idx_fp, $pos, SEEK_SET);
            $tmp_block = fread($this->idx_fp, DB_INDEX_SIZE);
            $cpkey = substr($tmp_block, 4, DB_KEY_SIZE);
            //$cpkey==$key时返回0,小于返回负数,大于返回正数
            if(!strncmp($cpkey, $key, $keylen)){
                $dataoff = unpack('L', substr($tmp_block, DB_KEY_SIZE + 4, 4));
                $dataoff = $dataoff[1];
                $datalen = unpack('L', substr($tmp_block, DB_KEY_SIZE + 8, 4));
                $datalen = $datalen[1];
                $found = true;
                break;
            }
            $prev = $pos;
            $pos = @unpack('L', substr($tmp_block, 0, 4));
            $pos = $pos[1];
        }

        if($found){
            return DB_KEY_EXISTS;
        }
        fseek($this->idx_fp, $prev, SEEK_SET);
        fwrite($this->idx_fp, pack('L', $idxoff), 4);
        fseek($this->idx_fp, 0, SEEK_END);
        fwrite($this->idx_fp, $block, DB_INDEX_SIZE);
        fseek($this->dat_fp, 0, SEEK_END);
        fwrite($this->dat_fp, $value, $vallen);
        return DB_SUCCESS;
    }

    /**
     * Description: 查询一条记录
     * @param $key
     */
    public function get($key){
        //计算偏移量,key的hash值对索引文件的大小求模,再乘4。因为每个链表指针大小为4
        $offset = ($this->times33Hash($key) % DB_BUCKET_SIZE) * 4;
        //SEEK_SET是默认的
        fseek($this->idx_fp, $offset, SEEK_SET);
        $pos = unpack('L', fread($this->idx_fp, 4));
        $pos = $pos[1];

        $found = false;
        while($pos){
            fseek($this->idx_fp, $pos, SEEK_SET);
            $block = fread($this->idx_fp, DB_INDEX_SIZE);
            $cpkey = substr($block, 4, DB_KEY_SIZE);

            if(!strncmp($key, $cpkey, strlen($key))){
                $dataoff = unpack('L', substr($block, DB_KEY_SIZE + 4, 4));
                $dataoff = $dataoff[1];

                $datalen = unpack('L', substr($block, DB_KEY_SIZE + 8, 4));
                $datalen = $datalen[1];

                $found = true;
                break;
            }
            $pos = unpack('L', substr($block, 0, 4));
            $pos = $pos[1];
        }
        if(!$found){
            return null;
        }
        fseek($this->dat_fp, $dataoff, SEEK_SET);
        $data = fread($this->dat_fp, $datalen);
        return $data;
    }

    /**
     * Description: 删除
     * @param $key
     */
    public function delete($key){
        $offset = ($this->times33Hash($key) % DB_BUCKET_SIZE) * 4;
        fseek($this->idx_fp, $offset, SEEK_SET);
        $head = unpack('L', fread($this->idx_fp, 4));
        $head = $head[1];
        $curr = $head;
        $prev = 0;
        $found = false;
        while($curr){
            fseek($this->idx_fp, $curr, SEEK_SET);
            $block = fread($this->idx_fp, DB_INDEX_SIZE);

            $next = unpack('L', substr($block, 0, 4));
            $next = $next[1];

            $cpkey = substr($block, 4, DB_KEY_SIZE);
            if(!strncmp($key, $cpkey, strlen($key))){
                $found = true;
                break;
            }
            $prev = $curr;
            $curr = $next;
        }
        if(!$found){
            return DB_FAILURE;
        }
        //删除索引文件。
        if($prev == 0){
            fseek($this->idx_fp, $offset, SEEK_SET);
            fwrite($this->idx_fp, pack('L', $next), 4);
        }else{
            fseek($this->idx_fp, $prev, SEEK_SET);
            fwrite($this->idx_fp, pack('L', $next), 4);
        }
        return DB_SUCCESS;
    }

    public function close(){
        if(!$this->closed){
            fclose($this->idx_fp);
            fclose($this->dat_fp);
            $this->closed = true;
        }
    }
}
?>


测试,测试添加一万条和查找一万条:

 代码如下 复制代码

<?php
//先include上面的类。。如果在同一个文件中就不用了。
//测试
$db = new DB();
$db->open('/var/www/data/');

$startTime = microtime(true);

//插入测试...插入10000条:成功,耗时: 793.48206520081ms
//for($i=0; $i<10000; $i++){
//    $db->add('key'.$i, 'value'.$i);
//}

//查找测试...查找10000条:成功,耗时: 149.08313751221ms
for($i=0; $i<10000; $i++){
    $db->get('key'.$i);
}

$endTime = microtime(true);
echo '成功,耗时: ' . (($endTime - $startTime)*1000) . 'ms';
$db->close();
?>

命名空间最初是在.net中可以使用了,不过现在php5.3开始也已经支持了命名空间这个东西了,下面一起来了解一下。


 PHP命名空间是PHP5.3开始支持。本篇讲解PHP命名空间用法和PHP命名空间详解。它的诞生使的我们在一个文件中可以使用多个同名的类而不冲突。
    好处:我们的项目有一个记录日志文件的类,叫做Log。然后我们又必须要引入另一个代码包,这个代码包里也有一个叫做Log的类。那么在一个文件中,我们记录日志的又需要给两个类都写一条日志。可以类同名了,怎么办?这个时候,命名空间应运而生。在Java等语言中命名空间是很早就已经提供了支持,而我大PHP一直到5.3才对命名空间提供了支持。
    示例一:
文件index.php
<?php
include 'test.php';

class index{
    public function a(){
        echo basename(__FILE__);
        echo '<br>';
        echo __CLASS__ . ' : ' . __METHOD__;
    }
}
$obj = new index();
$obj->a();
echo '<br>';
$obj1 = new test\index();
$obj1->a();
?>

文件test.php
<?php
namespace test;
class index{
    public function a(){
        echo basename(__FILE__);
        echo '<br>';
        echo __CLASS__ . ' : ' . __METHOD__;
    }
}
?>

    我们给index.php不设置命名空间,对test.php设置命名空间,名为test。运行index.php。
结果:
index.php
index : index::a
test.php
test\index : test\index::a

    我们看到了,同名的类也可以运行而不冲突了。

    示例二:
文件index.php
<?php
namespace index;
include 'test.php';

class index{
    public function a(){
        echo basename(__FILE__);
        echo '<br>';
        echo __CLASS__ . ' : ' . __METHOD__;
    }
}
$obj = new index();
$obj->a();
echo '<br>';
$obj1 = new \test\index();
$obj1->a();
?>

文件test.php
<?php
namespace test;
class index{
    public function a(){
        echo basename(__FILE__);
        echo '<br>';
        echo __CLASS__ . ' : ' . __METHOD__;
    }
}
?>

    我们给index.php设置命名空间,名为index,对test.php设置命名空间,名为test。运行index.php。
结果:
index.php
index\index : index\index::a
test.php
test\index : test\index::a

    比较示例一和二,不对index.php设置命名空间,即该文件是整个PHP全局命名空间下面的一个文件,那么使用test\index()即可,如果对index.php设置命名空间,即在其他的命名空间中使用命名空间,就要多一个“\”,就要使用\test\index()。

示例三:
文件index.php
<?php
namespace index;

include 'namespace.php';

use \test\test1\test2 as test2;

class index{
    public function a(){
        echo basename(__FILE__);
        echo '<br>';
        echo __CLASS__ . ' : ' . __METHOD__;
    }
}

$obj = new index();
$obj->a();

echo '<br>';

$obj1 = new \test\test1\test2\index();
$obj1->a();

echo '<br>';

$obj1 = new test2\index();
$obj1->a();

文件test.php
<?php
namespace test\test1\test2;
class index{
    public function a(){
        echo basename(__FILE__);
        echo '<br>';
        echo __CLASS__ . ' : ' . __METHOD__;
    }
}

结果:
index.php
index\index : index\index::a
test.php
test\test1\test2\index : test\test1\test2\index::a
test.php
test\test1\test2\index : test\test1\test2\index::a

    这说明了什么?别名!用过SQL吧。
select COUNT(*) as `count` from `tebleName`

    嗯,一个意思。\test\test1\test2这个名字太长了,就别名为test2就好了。使用了use之后呢,这个命名空间就想到于是在index这个命名空间下面了,而不是全局命名空间的一员了,所以使用test2\index(),而不是\test2\index()。

    别名时在PHP代码编译的时候执行的,而变量的解析则要更晚。也就是说不能对变量运用use关键字。示例如下(摘自官方手册示例):
<?php
use My\Full\Classname as Another, My\Full\NSname;

$obj = new Another; // 实例化一个 My\Full\Classname 对象
$a = 'Another';
$obj = new $a;      // 实际化一个 Another 对象

文件上传这个问题其实是一个很小的问题了,特别是php文件上传其实一句代码就可以实现了,但为了安全考虑我们会有一些其它的处理了,具体的操作步骤如下.

一个比较简单的php文件上传范例,可用于要求不高的时候,记录到这里,方便以后要用的时候直接过来复制。

$resume = $_FILES['resumefile'];
if($resume['name']!='')
{
 $enableType = array('jpg','png','gif','doc','docx','rtf','pdf'); //支持格式
 $maxSize = 1024*1024; //最大允许上传1M的文件
 $filePath = 'upload/resume/';
 $suffix = end(explode('.', $resume['name'])); //获取文件后缀名
 $resumeName = 'resume_'.time().'.'.$suffix;
 //大小限制
 if($resume['size']>$maxSize)
 {
  die("<script> alert('请上传1M以下的文件!'); history.back(); </script>");
 }
 //格式限制
 if(!in_array($suffix, $enableType))
 {
  die("<script> alert('格式不正确,请上传 ".implode(', ', $enableType)." 格式的文档!'); history.back(); </script>");
 }
 //上传
 if(move_uploaded_file($resume['tmp_name'], $filePath.$resumeName))
 {
  $attachment = $filePath.$resumeName; //文件名,写入数据库
 }
}

[!--infotagslink--]

相关文章

  • php语言实现redis的客户端

    php语言实现redis的客户端与服务端有一些区别了因为前面介绍过服务端了这里我们来介绍客户端吧,希望文章对各位有帮助。 为了更好的了解redis协议,我们用php来实现...2016-11-25
  • jQuery+jRange实现滑动选取数值范围特效

    有时我们在页面上需要选择数值范围,如购物时选取价格区间,购买主机时自主选取CPU,内存大小配置等,使用直观的滑块条直接选取想要的数值大小即可,无需手动输入数值,操作简单又方便。HTML首先载入jQuery库文件以及jRange相关...2015-03-15
  • JS实现的简洁纵向滑动菜单(滑动门)效果

    本文实例讲述了JS实现的简洁纵向滑动菜单(滑动门)效果。分享给大家供大家参考,具体如下:这是一款纵向布局的CSS+JavaScript滑动门代码,相当简洁的手法来实现,如果对颜色不满意,你可以试着自己修改CSS代码,这个滑动门将每一...2015-10-21
  • jQuery+slidereveal实现的面板滑动侧边展出效果

    我们借助一款jQuery插件:slidereveal.js,可以使用它控制面板左右侧滑出与隐藏等效果,项目地址:https://github.com/nnattawat/slideReveal。如何使用首先在页面中加载jquery库文件和slidereveal.js插件。复制代码 代码如...2015-03-15
  • PHP+jQuery翻板抽奖功能实现

    翻板抽奖的实现流程:前端页面提供6个方块,用数字1-6依次表示6个不同的方块,当抽奖者点击6个方块中的某一块时,方块翻转到背面,显示抽奖中奖信息。看似简单的一个操作过程,却包含着WEB技术的很多知识面,所以本文的读者应该熟...2015-10-21
  • SQLMAP结合Meterpreter实现注入渗透返回shell

    sqlmap 是一个自动SQL 射入工具。它是可胜任执行一个广泛的数据库管理系统后端指印, 检索遥远的DBMS 数据库等,下面我们来看一个学习例子。 自己搭建一个PHP+MYSQ...2016-11-25
  • PHP实现今天是星期几的几种写法

    复制代码 代码如下: // 第一种写法 $da = date("w"); if( $da == "1" ){ echo "今天是星期一"; }else if( $da == "2" ){ echo "今天是星期二"; }else if( $da == "3" ){ echo "今天是星期三"; }else if( $da == "4"...2013-10-04
  • 原生js实现fadein 和 fadeout淡入淡出效果

    js里面设置DOM节点透明度的函数属性:filter= "alpha(opacity=" + value+ ")"(兼容ie)和opacity=value/100(兼容FF和GG)。 先来看看设置透明度的兼容性代码: 复制代码 代码如下: function setOpacity(ele, opacity) { if (...2014-06-07
  • C#实现图片放大功能的按照像素放大图像方法

    这篇文章主要介绍了C#实现图片放大功能的按照像素放大图像方法,功能非常实用,需要的朋友可以参考下...2020-06-25
  • python中翻译功能translate模块实现方法

    在本篇文章中小编给各位整理了一篇关于python中翻译功能translate模块实现方法,有需要的朋友们可以参考下。...2020-12-18
  • Android中用HttpClient实现Http请求通信

    本文我们需要解决的问题是如何实现Http请求来实现通信,解决Android 2.3 版本以后无法使用Http请求问题,下面请看正文。 Android开发中使用HttpClient来开发Http程序...2016-09-20
  • mysql存储过程实现split示例

    复制代码 代码如下:call PROCEDURE_split('分享,代码,片段',',');select * from splittable;复制代码 代码如下:drop PROCEDURE if exists procedure_split;CREATE PROCEDURE `procedure_split`( inputstring varc...2014-05-31
  • AngularJS 让人爱不释手的八种功能

    AngularJS 让人爱不释手的八种功能,想知道AngularJS哪八种功能让人喜欢就快点看下本文吧...2016-03-28
  • 微信小程序实现导航功能的操作步骤

    这篇文章主要给大家介绍了关于微信小程序实现导航功能的操作步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-10
  • EMUI11上手体验 新颜值/新功能/新体验

    EMUI11值得升级吗?好不好用?下面小编带来EMUI11上手体验,一起来看看手机鸿蒙OS的提前预演...2020-12-08
  • phpMyAdmin 高级功能设置的方法图解

    phpmyadmin还有高级功能可能大部份站长不知道吧,今天本文章就来给大家介绍phpMyAdmin 高级功能设置的方法图解,希望文章对大家会有所帮助。 phpMyAdmin 安装后,默认...2016-11-25
  • 小爱同学5.0新增了哪些机型 小爱同学5.0新功能介绍

    小爱同学5.0即将发布,据已知报道小爱同学5.0将新增机型,跟着小编一起来看看吧,顺便了解下即将都有哪些新功能面市吧...2020-12-08
  • 很全面的JavaScript常用功能汇总集合

    这篇文章主要为大家分享了一份很全面的JavaScript常用功能汇总集合,一些常用的额JS 对象、基本数据结构、功能函数等,感兴趣的小伙伴们可以参考一下...2016-01-24
  • css实现文字发光效果方法汇总

    文字发光效果我们可以直接使用css来实现了今天我们来看一篇关于文字发光效果的例子,希望这篇文章能够帮助到各位朋友哦。 前言 我录制的慕课网视频一直没有上线,慕...2016-09-14
  • PHP+Mysql+Ajax+JS实现省市区三级联动

    基本思想就是:在JS动态创建select控件的option,通过Ajax获取在PHP从SQL数据库获取的省市区信息,代码有点长,但很多都是类似的,例如JS中省、市、区获取方法类似,PHP中通过参数不同执行不同的select语句。index.html代码:复制...2014-05-31