一. 什么是memcached
memcached 是一个高性能的分布式内存对象缓存系统,用于动态web应用以减轻数据库教程负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态、数据库驱动网站的速度。
相信很多人都用过缓存,在 .net 中也有内置的缓存机制,还有很多第三方工具如apache,nginx等可以做静态资源的缓存,同时我们也可以制定自己的缓存机制,缓存数据库查询的数据以减少对数据库的频繁操作。但是很多时候我们总是感觉这些缓存总不尽人意, memcached可以解决你不少的烦恼问题。最少在我的学习中解决了我不少问题,所以决定记录下来分享。
memcached基于一个存储键/值对的hashmap。其守护进程是用c写的,但是客户端可以用任何语言来编写(本文使用c#作为例子),并通过memcached协议与守护进程通信。可 能这些东西都太高深了,我们暂不做研究。
二. 分布式缓存
其实 memcached作为一个分布式缓存数据服务,但是每个服务之间根本没有进行相互通信,这里可能与我理解的分布式有点区别,可能是我才疏学浅,也可能是每个人思考问题的角度不同。memcached 客户端就是通过一种分布式算法将数据保存到不同的memcached服务器上,将数据进行缓存。分布式缓存,可以而知memcached可以进行大数据量的缓存。这点可以弥补我们之前很多人都遇到的将数据缓存到应用服务器上,而且只能缓存少量数据,否则对应用服务器的影响非常大。
memcached应用机制图:
![]()
这个图是有点简陋了,但是问题还是能够描述的清楚的,缓存机制的基本原理就是先查询数据保存到memcached中,地址在此请求就直接从memcached缓存中取数据,这样就可以减少对服务器请求压力。
codeigniter 具有非常容易使用的分页类。在本教程中我会做一个从数据库教程返回一组结果并分页这些结果的简单例子。我将使用最新版本的 ci。分页类并没有修改(至少我认为没有),用最新的稳定版框架总是好的
调用方法
//创建分页
$config = array();
$this->load->library('hpages');
$config['base_url'] = "channel/lists/c{$slug}/{page}";
$config['total_rows'] = intval($total);
$config['per_page'] = $pagesize;
$config['uri_segment'] = 1;
$config['num_links'] = 3;
$config['underline_uri_seg'] = 1; //下划线uri中页数所在的位置
$this->hpages->init($config);
$this->template['lists'] = $list;
$this->template['pagestr'] = $this->hpages->create_links(1);
php教程文件代码
<?php if (! defined('basepath')) exit('access denied!');
/**
* file_name : hpages.php
* 浩海网络 前台 分页类
*
* @package haohailuo
* @author by laurence.xu <haohailuo@163.com>
* @copyright copyright (c) 2010, haohailuo, inc.
* @link http://www.haohailuo.com
* @since version 1.0 $id$
* @version wed dec 08 12:21:17 cst 2010
* @filesource
*/
class hpages {var $base_url = ''; //基本链接地址
var $total_rows = ''; //数据总数
var $per_page = 10; //每页条数
var $num_links = 2; //要显示的左右链接的个数
var $cur_page = 1; //当前页数
var $first_link = '‹ first'; //首页字符
var $next_link = '>'; //下一页的字符
var $prev_link = '<'; //上一页的字符
var $last_link = 'last ›'; //末页的字符
var $uri_segment = 3; //分页数所在的uri片段位置
var $full_tag_open = ''; //分页区域开始的html标签
var $full_tag_close = ''; //分页区域结束的后html标签
var $first_tag_open = ''; //首页开始的html标签
var $first_tag_close = ' '; //首页结束的html标签
var $last_tag_open = ' '; //末页开始的html标签
var $last_tag_close = ''; //末页结束的html标签
var $cur_tag_open = ' <b>';//当前页开始的...
var $cur_tag_close = '</b>'; //当前页结束的...
var $next_tag_open = ' '; //下一页开始的.....
var $next_tag_close = ' '; //下一页结束的.....
var $prev_tag_open = ' '; //上一页开始的.....
var $prev_tag_close = ''; //上一页结束的.....
var $num_tag_open = ' '; //“数字”链接的打开标签。
var $num_tag_close = ''; //“数字”链接的结束标签。
var $page_query_string = false;
var $query_string_segment = 'per_page';
var $page_mode = 'default'; //default for add page at the end? if include {page}, will replace it for current page.
var $underline_uri_seg = -1; //存在下划线时,页码所在数组下标位置
var $custom_cur_page = 0; //自定义当前页码,存在此值是,系统将不自动判断当前页数,默认不启用
function __construct() {
$this->hpages();
}
/**
* constructor
*
* @access public
*/
function hpages() {
if (file_exists(apppath.'config/pagination.php')) {
require_once(apppath.'config/pagination.php');
foreach ($config as $key=>$val) {
$this->{$key} = $val;
}
}
log_message('debug', "hpages class initialized");
}
/**
* 初始化参数
*
* @see init()
* @author laurence.xu <haohailuo@163.com>
* @version wed dec 08 12:26:07 cst 2010
* @param <array> $params 待初始化的参数
*/
function init($params = array()) {
if (count($params) > 0) {
foreach ($params as $key => $val) {
if (isset($this->$key)) {
$this->$key = $val;
}
}
}
}
/**
* 创建分页链接
*
* @see create_links()
* @author laurence.xu <haohailuo@163.com>
* @version wed dec 08 15:02:27 cst 2010
* @param <boolean> $show_info 是否显示总条数等信息
* @return <string> $output
*/
function create_links($show_info = false, $top_info = false) {
//如果没有记录或者每页条数为0,则返回空
if ($this->total_rows == 0 || $this->per_page == 0) {
return '';
}//计算总页数
$num_pages = ceil($this->total_rows / $this->per_page);//只有一页,返回空
if ($num_pages == 1 && !$show_info) {
return '';
}
$ci =& get_instance();//获取当前页编号
if ($ci->config->item('enable_query_strings') === true || $this->page_query_string === true) {
if ($ci->input->get($this->query_string_segment) != 0) {
$this->cur_page = $ci->input->get($this->query_string_segment);// prep the current page - no funny business!
$this->cur_page = (int) $this->cur_page;
}
} else {
if (intval($this->custom_cur_page) > 0) {
$this->cur_page = (int) $this->custom_cur_page;
}else{
$uri_segment = $ci->uri->segment($this->uri_segment, 0);
if ( !empty($uri_segment) ) {
$this->cur_page = $uri_segment;
//如果有下划线
if ($this->underline_uri_seg >= 0) {
if (strpos($this->cur_page, '-') !== false) {
$arr = explode('-', $this->cur_page);
}else {
$arr = explode('_', $this->cur_page);
}
$this->cur_page = $arr[$this->underline_uri_seg];
unset($arr);
}
// prep the current page - no funny business!
$this->cur_page = (int) $this->cur_page;
}
}
}
//echo $this->cur_page;exit;
//左右显示的页码个数
$this->num_links = (int)$this->num_links;if ($this->num_links < 1) {
show_error('your number of links must be a positive number.');
}if ( ! is_numeric($this->cur_page) || $this->cur_page < 1) {
$this->cur_page = 1;
}
//如果当前页数大于总页数,则赋值给当前页数最大值
if ($this->cur_page > $num_pages) {
$this->cur_page = $num_pages;
}$uri_page_number = $this->cur_page;
if ($ci->config->item('enable_query_strings') === true || $this->page_query_string === true) {
$this->base_url = rtrim($this->base_url).'&'.$this->query_string_segment.'=';
} else {
$this->base_url = rtrim($this->base_url, '/') .'/';
}
if (strpos($this->base_url, "{page}") !== false) {
$this->page_mode = 'replace';
}
$output = $top_output = '';
//数据总量信息
if ($show_info) {
$output = " 共<b>".$this->total_rows ."</b>条记录 <span style='color:#ff0000;font-weight:bold'>{$this->cur_page}</span>/<b>".$num_pages."</b>页 每页<b>{$this->per_page}</b>条 ";
}
//数据信息,显示在上面,以供提醒
if ($top_info) {
$top_output = " 共 <b>".$this->total_rows ."</b> 条记录 第<span style='color:#ff0000;font-weight:bold'>{$this->cur_page}</span>页/共<b>".$num_pages."</b>页 ";
}
//判断是否要显示首页
if ($this->cur_page > $this->num_links+1) {
$output .= $this->first_tag_open.'<a href="'.$this->makelink().'">'.$this->first_link.'</a>'.$this->first_tag_close;
}
//显示上一页
if ($this->cur_page != 1) {
$j = $this->cur_page - 1;
if ($j == 0) $j = '';
$output .= $this->prev_tag_open.'<a href="'.$this->makelink($j).'">'.$this->prev_link.'</a>'.$this->prev_tag_close;
}
//显示中间页
for ($i=1; $i <= $num_pages; $i++){
if ($i < $this->cur_page-$this->num_links || $i > $this->cur_page+$this->num_links) {
continue;
}
//显示中间页数
if($this->cur_page == $i){
$output .= $this->cur_tag_open.$i.$this->cur_tag_close; //当前页
}else {
$output .= $this->num_tag_open.'<a href="'.$this->makelink($i).'">'.$i.'</a>'.$this->num_tag_close;
}
}
//显示下一页
if ($this->cur_page < $num_pages) {
$k = $this->cur_page + 1;
$output .= $this->next_tag_open.'<a href="'.$this->makelink($k).'">'.$this->next_link.'</a>'.$this->next_tag_close;
}
//显示尾页
if (($this->cur_page + $this->num_links) < $num_pages) {
$output .= $this->last_tag_open.'<a href="'.$this->makelink($num_pages).'">'.$this->last_link.'</a>'.$this->last_tag_close;
}$output = preg_replace("#([^:])//+#", "1/", $output);
// add the wrapper html if exists
$output = $this->full_tag_open.$output.$this->full_tag_close;if ($top_info) {
return array($output, $top_output);
}else {
return $output;
}
}
/**
* 创建链接url地址
*
* @param <string> $str
* @return <string>
*/
function makelink($str = '') {
if($this->page_mode == 'default') {
return $this->_forsearch($this->base_url.$str);
} else {
$url = $this->base_url;
if ($str == 1) {
$url = str_replace('/{page}', '', $this->base_url);
}
$url = str_replace("{page}", $str, $url);
return $this->_forsearch($url);
}
}
/**
* 处理url地址
*
* @see _forsearch()
* @author laurence.xu <haohailuo@163.com>
* @version wed dec 08 14:33:58 cst 2010
* @param <string> $string pinfo
* @return <string>
*/
function _forsearch($string) {
$length = strlen($string) - 1;
if($string{$length} == '/') {
$string = rtrim($string, '/');
}
return site_url($string);
return $string;
}
}// end pagination class
/* end of file hpages.php */
/* location: ./system/libraries/hpages.php */
1.正常的touch创建word
2.fopen 打开word
3.fwrite 写入word 并保存
这样会出现一个问题 如果写入的东西里面含有html代码的话,它将直接写入word而不是 排版了
这个问题 需要在输出html 代码头部加一段代码
$headert='<html xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:w="urn:schemas-microsoft-com:office:word"
xmlns="http://www.w3.org/tr/rec-html40">';
$footer="</html>";
比如你的内容是$text;
那么写入的时候$text=$header.$text.$footer;
这样的话fck里面的东西就能按排版的样式输出了!
方法一
<?php
$word= new com("word.application") or die("unable to
create word document");
print "loaded word, version{$word->version}n";
$word->visible =0;
$word->documents->add();
//设置边距 这个有错误
// $word->selection->agesetup->rightmargin ='3"';
//设置字体 这
$word->selection->font->name ='helvetica';
//设置字号
$word->selection->font->size = 8;
//设置颜色
$word->selection->font->colorindex= 13; //wddarkred= 13
//输出到文档
$word->selection->typetext("hello world ");
$range = $word->activedocument->range(0,0);
$table_t =$word->activedocument->tables->add($range,3,4);
$table_t->cell(1,2)->range->insertafter('aaa');
//保存
//$word->sections->add(1);
$word->documents[1]->saveas(dirname(__file__)."/create_test.doc");
//退出
$word->quit();
?>
方法二
<?php
class word
{
function start()
{
ob_start();
print'<html xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:w="urn:schemas-microsoft-com:office:word"
xmlns="http://www.w3.org/tr/rec-html40">';
}
function save($path)
{
print "</html>";
$data = ob_get_contents();
ob_end_clean();
$this->wirtefile ($path,$data);
}
function wirtefile ($fn,$data)
{
$fp=fopen($fn,"wb");
fwrite($fp,$data);
fclose($fp);
}
}
?>
调用方法
$word=new word;
$word->start();
echo $cout;
$wordname="word/".time().".doc";
$word->save($wordname);//保存word并且结束
1. 数组
php教程的数组其实是一个关联数组,或者说是哈希表。php不需要预先声明数组的大小,可以用直接赋值的方式来创建数组。例如:
//最传统,用数字做键,赋值
$state[0]="beijing";
$state[1]="hebei";
$state[2]="tianjin";
//如果键是递增的数字,则可以省略
$city[]="shanghai";
$city[]="tianjin";
$city[]="guangzhou";
//用字符串做键
$capital["china"]="beijing";
$capital["japan"]="tokyo";
用array()来创建数组会更加方便一点,可以将数组元素作为array的参数传递给他,也可以用=>运算符创建关联数组。例如:
$p=array(1,3,5,7);
$capital=array(“china”=>”beijing”, “japan=>”tokyo”);
array其实是一种语法结构,而不是函数。和array类似,还有一个list(),它可以用来提取数组中的值,并给多个变量赋值。例如:
list($s,$t)=$city;
echo $s,' ',$t;
输出结果:shanghai tianjin
注意,list方法只能用于由数字索引的数组。
php内建了一些常用的数组处理函数,具体可以参考手册。常用的函数举例如下,count或者sizeof可以得到数组的长度,array_merge 可以合并两个,或者多个数组,array_push(pop)可以像堆栈一样使用数组。
利用form表单的target属性和iframe
一、上传文件的一个php教程方法。
该方法接受一个$file参数,该参数为从客户端获取的$_files变量,返回重新命名后的文件名,如果上传失败,则返回空字符串。
php代码
function uploadfile($file) {
// 上传路径 $destinationpath = "./upload/";
if (!file_exists($destinationpath)){
mkdir($destinationpath , 0777); }
//重命名
$filename = date('ymdhis') . '_' . iconv('utf-8' , 'gb2312' , basename($file['name']));
if (move_uploaded_file($file['tmp_name'], $destinationpath . $filename)) { return iconv('gb2312' , 'utf-8' , $filename);
} return '';
}
二、客户端html代码
这里正是技巧所在,添加另一个iframe来实现。表单标签form定义了一个属性target,该属性解释如下:
[pre]target属性:
_blank ---------- 新开窗口
_self ----------- 自身
_top ------------ 主框架
_parent --------- 父框架
自定义名字 ----- 出现于框架结构,将会在该名称的框架内打开链接
本例中采用iframe名字,所以表单在提交时会在iframe内打开链接(即无刷新,确切的说应该是
感觉无刷新)
在表单提交时,调用startupload方法,当然这是js定义的。
[/pre][pre]此外我们还定义一个span来显示提示信息。代码如下:
[/pre]xhtml代码
<form id="upform" action="upload.php" method="post" enctype="multipart/form-data" target="upload_target" onsubmit="startupload()"> 导入文件:<input type="file" name="myfile" id="myfile" />
<input type="submit" name="submitbtn" value="导入" /> <iframe id="upload_target" name="upload_target"" width=100% src="#" style="width:0;height:0;border:0px solid #fff;">iframe>
form> <span id="info">span>