作者归档:℃冻番茄

通过php web方式更新服务器svn[新]

主要的功能为二点:1、签出svn,2、更新svn;

需事前注意:apache或是nginx+php 用户要有svn程序执行的权限,如果没有的话,就需要通过visudo进行sudo授权,让apache用户(例www-data)可以执行svn程序

visudo文件最后加上:(意思:sudo无需输入密码可执行/usr/bin/svn命令)
www-data ALL = NOPASSWD:/usr/bin/svn

界面:

1.png

2.png

3.png

4.png

 

注意:如果通过visudo的方式让apache等执行svn命令,则下面的php代码中的svn 需改成sudo svn …..

<?php
//author 冻番茄 www.phpd.cn
session_start();
//echo $_SERVER['REQUEST_URI'];
//print_r($_SERVER);
//location.reload();

function update(){
	echo '<h2>svn update ...</h2>';
	//echo "svn up --username {$_SESSION['username']} --password {$_SESSION['password']} ";
	$hl=popen("svn up --username {$_SESSION['username']} --password {$_SESSION['password']} ","r");
	$read=stream_get_contents($hl);
	echo "<pre>";
	printf($read);
	echo "</pre>";
	pclose($hl);
}

function co($url,$username,$password){
	echo '<h2>svn checkout ...</h2>';
	$command="svn co $url --username {$_SESSION['username']} --password {$_SESSION['password']} ".$_SERVER['DOCUMENT_ROOT'];
	exec($command);
	echo 'checkout Success!';
}
if(isset($_POST['sub']) && $_POST['sub']=="登录"){
	if($_POST['password']=="7279915"){
		$_SESSION['login']=true;
		echo '<script>location.href="'.$_SERVER['PHP_SELF'].'";</script>';
	}else{
		echo '<script>alert("PASSWORD ERROR");location.href="'.$_SERVER['PHP_SELF'].'";</script>';
	}
	exit;
}elseif(isset($_POST['sub']) && $_POST['sub']=='执行'){
	if(empty($_POST['username']) || empty($_POST['password'])){
		echo '<script>alert("SVN服务器的用户名或是密码不能为空");location.href="?a=update";</script>';
	}else{
		$_SESSION['username']=$_POST['username'];
		$_SESSION['password']=$_POST['password'];
		echo '<script>location.href="?a=update";</script>';
	}
	exit;
}

if(isset($_GET['a']) && $_GET['a']=='logout'){
	unset($_SESSION['login']);
	unset($_SESSION['username']);
	unset($_SESSION['password']);
	echo '<script>location.href="?a=co";</script>';
	exit;
}

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>svn更新 | Author:常州亚萌 冻番茄</title>
<style>
*{ margin:0px; padding:0px; font-size:12px;font-family:Arial,Helvetica,sans-serif}
a:link,a:visited,a:active{ color:#5A5A5A; text-decoration:none;font-size:14px;}
a:hover{ color:#33A9D0; text-decoration:none;}
.login{margin:0px auto;margin-top:200px;border:1px solid #666600;width:300px;height:90px;background:#FFFFD0}
input{border:1px solid #666600;background:#fff;width:160px;padding:3px;}
.in1{border:1px solid #666600;background:#fff;width:120px;padding:2px;font-size:9px;}
.run{margin:20px auto;;width:700px;height:90px}
h2{padding-bottom:8px;}
</style>
</head>
<body>
<?php
if(!isset($_SESSION['login'])){
?>
<div class="login">
	<FORM METHOD=POST ACTION="">
	<div style="font-size:14px;margin:10px;border-bottom:1px solid #666600;padding-bottom:10px;text-align:center">svn更新操作 [管理员登录]</div>
	<div style="margin:10px;clear:both;text-align:center"><INPUT TYPE="password" NAME="password">&nbsp;&nbsp; <INPUT TYPE="submit" name="sub" value="登录" style="width:70px;height:25px;"></div>
	</FORM>
</div>
<?php
}else{	
?>
<div class="run">
	<div style="font-size:14px;margin:10px;border-bottom:1px solid #666600;padding-bottom:10px;"> [<a href="?a=update">svn刷新/upload</a>] [<a href="?a=co">svn签出/checkout</a>]  [<a href="/svn.php?a=logout">退出</a>]</div>
	<div style="margin:10px;clear:both;">
		<?php
			if(isset($_GET['a']) && $_GET['a']=='update'){
				if(!isset($_SESSION['username']) || !isset($_SESSION['password'])){
					echo '<FORM METHOD=POST ACTION="">
							<h2>SVN更新操作</h2>
							<div>svn用户名:<INPUT TYPE="text" NAME="username" class="in1">
								svn密码:<INPUT TYPE="password" NAME="password" class="in1">
								<INPUT TYPE="submit" name="sub" value="执行" style="width:70px;background:#eee" class="in1">
							</div>
						</FORM>';
				}else{
					update();
				}
			}elseif(isset($_GET['a']) && $_GET['a']=='co'){
				if(isset($_POST['sub']) && $_POST['sub']=='签出'){
					if(empty($_POST['username']) || empty($_POST['password']) || empty($_POST['svn']) ){
						echo '<script>alert("签出的svn地址、用户名、密码不能为空");location.href="?a=co";</script>';
					}else{
						$_SESSION['username']=$_POST['username'];
						$_SESSION['password']=$_POST['password'];
						co($_POST['svn']);
					}
					exit;
				}
				echo '<FORM METHOD=POST ACTION="">
							<h2>SVN签出操作 <注:已签出的项目,第二次签出无效!></h2>
							<div>svn地址:<INPUT TYPE="text" NAME="svn" class="in1" value="svn://">
								svn用户名:<INPUT TYPE="text" NAME="username" class="in1">
								svn密码:<INPUT TYPE="password" NAME="password" class="in1">
								<INPUT TYPE="submit" name="sub" value="签出" style="width:70px;background:#eee" class="in1">
							</div>
						</FORM>';
			}else{
				echo '欢迎进入svn更新程序!Author:冻番茄<br />';
			}
		?>
		<div style="clear:both;height:10px"></div>
	</div>
	
</div>
<?php
}
?>
</body>
</html>

源代码下载:

svn.php

快速开发一个PHP扩展 [转heiyeluren]

本文通过非常快速的方式讲解了如何制作一个PHP 5.2 环境的扩展(PHP Extension),希望能够在图文的方式下让想快速学习的朋友了解一下制作过程。


需求:比如开发一个叫做 heiyeluren  的扩展,扩展里就一个函数 heiyeluren_test(),输入一个字符串,函数返回:Your input string: xxxxx。
要求:了解C/C++编程,熟悉PHP编程
环境:下载一份php对应版本的源码,我这里是 php-5.2.6,先正常安装php,假设我们的php安装在 /usr/local/php 目录,源码在 /root/soft/php/php-5.2.6/,现在开始!


步骤一:生成扩展框架


cd /root/soft/php/php-5.2.6/ext
./ext_skel –extname=heiyeluren
cd /root/soft/php/php-5.2.6/ext/heiyeluren
vi config.m4
打开文件后去掉 dnl ,获得下面的信息:
PHP_ARG_ENABLE(heiyeluren, whether to enable heiyeluren support,
[  –enable-heiyeluren           Enable heiyeluren support])

保存退出.
(图01)

 

 

第二步:编写代码

vi php_heiyeluren.h
找到:PHP_FUNCTION(confirm_heiyeluren_compiled); ,新增一行:
PHP_FUNCTION(heiyeluren_test);
保存退出。
(图02)


vi heiyeluren.c
数组里增加我们的函数,找到 zend_function_entry heiyeluren_functions[],增加:
PHP_FE(heiyeluren, NULL)
(图03)

 

再到 heiyeluren.c 文件最后面增加如下代码:
PHP_FUNCTION(heiyeluren_test)
{
    char *arg = NULL;
    int arg_len, len;
    char *strg;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
        return;
    }

    len = spprintf(&strg, 0, "Your input string: %s\n", arg);
    RETURN_STRINGL(strg, len, 0);
}
保存退出。
(图04)

 

 

 

第三步:编译安装

cd /root/soft/php/php-5.2.6/ext/heiyeluren
/usr/local/php/bin/phpize
./configure –with-php-config=/usr/local/php/bin/php-config
make
make test
make install

现在看看是不是有个 /usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/heiyeluren.so
编辑php.ini,把扩展加入进去:
vi /usr/local/php/lib/php.ini
在[PHP]模块下增加:
extension = heiyeluren.so
保存退出。
(图05)

 

注意:如果你不存在扩展文件目录,或者安装报错,那么可以自行建立这个目录,然后把扩展拷贝到目录下,然后记得把 php.ini 文件中的 extension_dir 修改为该目录:
extension_dir = "/usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/"
(图06)

 

 

第四步:检查安装结果
现在看看模块加载了没有:
/usr/local/php/bin/php -m,应该会打印出:
[PHP Modules]

heiyeluren

[Zend Modules]


然后重启apache,输出 phpinfo() ,应该能够看到:
heiyeluren
heiyeluren support enabled

(图07)

 

看看函数是否存在并且调用,在web目录下建立:heiyeluren.php
<?php
echo "<pre>";
print_r(get_loaded_extensions());
print_r(get_extension_funcs('heiyeluren'));
echo heiyeluren_test('My first php extension');
echo "</pre>";
?>

访问apache,应该能够看到:
Array
(
    …
    [33] => heiyeluren
)
Array
(
    [0] => confirm_heiyeluren_compiled
    [1] => heiyeluren_test
)
Your input string: heiyeluren
(图08)


扩展制作成功!

新写的一个.net小程序,用于批量搜索源码内容

主要是解决在工作中,有些需要在大批量的源文件或是html中搜索文本中包括一些关键词的操作。比如搜索全部的html,查找出哪个文章被挂了马,又比如说查看一个开源软件源码时,要找到一个函数定义所在文件。有了这个小软件,就方便多了

目前是第一版只支持utf-8编码,过段时间,加上编码转换功能,就可以支持其它编码了!编码只在搜索中文时有影响,英文不受影响

程序截图

txtsearch.png

程序下载

txtsearch.zip

刚写的的php生成树的类 [读一次数据库,支持无限分类]

从数据库中一次性读取全部的分类信息,然后将由php生成树,支持无限分类,采用的方式是父值,容易理解,效率比起其它类似左右值的无限分类,当类别过多时可能效率要差些!

CREATE TABLE IF NOT EXISTS `membercat` (
  `mcid` int(10) NOT NULL auto_increment COMMENT '会员分类ID号',
  `mcname` varchar(255) NOT NULL COMMENT '分类名称',
  `fid` int(10) default NULL COMMENT '父ID号',
  `rank` int(10) default NULL COMMENT '级别',
  `mcorder` int(10) NOT NULL COMMENT '排序',
  PRIMARY KEY  (`mcid`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COMMENT='个人会员分类表' AUTO_INCREMENT=13 ;

--
-- 导出表中的数据 `membercat`
--

INSERT INTO `membercat` (`mcid`, `mcname`, `fid`, `rank`, `mcorder`) VALUES
(1, '平面设计', 0, 1, 1),
(2, 'UI设计', 0, 1, 2),
(3, 'CG/动画', 0, 1, 3),
(4, '工业设计', 0, 1, 4),
(5, '建筑/环境', 0, 1, 5),
(7, '2222', 2, 2, 6),
(8, '1111', 2, 2, 9),
(9, '3333', 7, 3, 8),
(10, '4444', 4, 2, 10),
(11, '5555', 3, 2, 11),
(12, 'asdasd', 8, 3, 12);

php类

<?php
class getMemberCat
{
	public $c=array();
	public $arr='';

	public function __construct()
	{
		$membercat_=db('membercat');
		if($cat=$membercat_->order("mcorder")->findAll()){
			foreach($cat as $v){
				$this->c[$v['rank']][]=$v;
			}
			for($s=0;$s<count($this->c[1]);$s++){
				$this->arr[]=array('name'=>$this->c[1][$s]['mcname'],'mcid'=>$this->c[1][$s]['mcid']);
				$this->get($this->c[1][$s]['mcid'],2);
			}
		}
		return $this->arr;
	}

	public function get($fid,$j)
	{
		$px="";
		for($x=1;$x<$j;$x++){
			$px.="&nbsp;&nbsp;&nbsp;&nbsp;";
		}
		$px=empty($px)?"":$px."└--";
		
		for($i=0;$i<count($this->c[$j]);$i++){
			if($this->c[$j][$i]['fid']==$fid){
				$this->arr[]=array('name'=>$px.$this->c[$j][$i]['mcname'],'mcid'=>$this->c[$j][$i]['mcid']);
				$this->get($this->c[$j][$i]['mcid'],$j+1);
			}
		}
		
	}
}
$mCat=new getMemberCat();
foreach($mCat->arr as $v){
	echo $v['name'].'<br />';
}
?>

最终显示结果:

平面设计
UI设计
    └–2222
        └–3333
    └–1111
        └–asdasd
CG/动画
    └–5555
工业设计
    └–4444
建筑/环境

RESTful,在不用session的情况下做用户认证

最近在研究restful,在restful协议中,强调不使用session,但可以少量使用cookie。以保持restful的无状态性。

但是在实际使用中,有一个最大的问题,就是当应用需要用户登陆认证时,应该怎么处理。

在这里我的处理方法主要是把用户登陆后,把用户名+密码+ip地址+最后更新时间通过一个可逆加密后做为token,写入cookie,然后在需要认证的应用时,由php等程序读取cookie中的token,并把用户名、密码、ip地址及最后更新时间解密出来。

先判断时间是否过期,过期的话,清除cookie,要求重新登陆!

再判断cookie中的ip是否与当前客户端ip一致,如果不等,要求重新登陆。

时间和ip都通过的话,则把用户名、密码做判断,判断是否正确,正确的话,把用户基本信息存在一全局变量中!

做后续应用,同时把生成新的token(主要是时间)写入cookie。

这样的话就解决了三个问题

第一、时效,cookie有一个生存时间、同时在token中也存储时间,方便让令牌失效;

第二、解决了cookie欺骗问题,因为token记录了客户端的ip地址;

第三、解决了安全问题,采用可逆加密,就算得到token在没有解密key的情况下也无法破解得用户名及密码。

 

还有一个情况,同时把token保存到服务器,这样更容易控制!但是把东西记录到服务器的话,其实它不就是session了么,伪session而以,所以还是不建议这么用!

昨天把博客升级成了sablog 2.0

08年使用小a的sablog 1.6博客程序就一直没有改变过,现在都2010年了,应该有些变化了,所以就把博客升级到了2.0,以后,第一个感觉就是后台更清爽了。

升级到2.0后,因为url有所变化,0为了不影响百度里的文章收录,用.htaccess做了301转向。


新博客新气象,嘿嘿,以后要我写些东西发上去了,同时也诚招同类博客的友情链接!

今天给xpad加上了QQ机器人功能

感谢 http://im.jecat.cn/demo/ 提供的开源qq机器人程序

今天把qq机器人整到我的xpad应用中去了,但因为qq机器人程序运行在美国的vps上,xpad运行在新浪的sae上。所以速度有些迟缓。

新给xpad加的qq机器人,用户注册xpad后,直接在后台进行绑定qq号操作,然后添加机器人的qq号为好友,就可以使用xpad便捷的qq机器人服务了。

http://xpad.sinaapp.com

 

1.png2.png3.png4.png5.png6.png

firefox poster不能上传文件,测试文件方面还得用curl

白.png

没法上传,把Content Type设为multipart/form-data也一样无效,不知道是不是bug,google上也没找到解释。

所以测试上传只能靠curl了,但是curl的cookie挺麻烦的,现在把我测试文件上传的命令发到博客里,希望有用得上的朋友借鉴。

第一条是登陆,获取session,把PHPSESSID的cookie存入cookie33.txt

curl -X POST -d "username=admin&password=admin" "http://localhost:88/?m=index&a=ajaxlogin" -D cookie33.txt

第二条是进入一个受session保护的页面,-b获取发送cookie到服务器,-c重新写入新cookie操作,得到session授权,从而准许打开页面

curl "http://localhost:88/?m=main" -b cookie33.txt -c cookie33.txt

第三条是把文件上传到一个受session保护的页面-F是上传文件

curl -F "file=@a.jpg" "localhost:88/?m=main&a=upload" -b cookie33.txt -c cookie33.txt