放着备查
* –b 当file存在并且是块文件时返回真
* -c 当file存在并且是字符文件时返回真
* -d 当pathname存在并且是一个目录时返回真
* -e 当pathname指定的文件或目录存在时返回真
* -f 当file存在并且是正规文件时返回真
* -g 当由pathname指定的文件或目录存在并且设置了SGID位时返回为真
* -h 当file存在并且是符号链接文件时返回真,该选项在一些老系统上无效
* -k 当由pathname指定的文件或目录存在并且设置了“粘滞”位时返回真
* -p 当file存在并且是命令管道时返回为真
* -r 当由pathname指定的文件或目录存在并且可读时返回为真
* -s 当file存在文件大小大于0时返回真
* -u 当由pathname指定的文件或目录存在并且设置了SUID位时返回真
* -w 当由pathname指定的文件或目录存在并且可执行时返回真。一个目录为了它的内容被访问必然是可执行的。
* -o 当由pathname指定的文件或目录存在并且被子当前进程的有效用户ID所指定的用户拥有时返回真。
UNIX Shell 里面比较字符写法:
* -eq 等于
* -ne 不等于
* -gt 大于
* -lt 小于
* -le 小于等于
* -ge 大于等于
* -z 空串
* = 两个字符相等
* != 两个字符不等
* -n 非空串
* –b 当file存在并且是块文件时返回真
* -c 当file存在并且是字符文件时返回真
* -d 当pathname存在并且是一个目录时返回真
* -e 当pathname指定的文件或目录存在时返回真
* -f 当file存在并且是正规文件时返回真
* -g 当由pathname指定的文件或目录存在并且设置了SGID位时返回为真
* -h 当file存在并且是符号链接文件时返回真,该选项在一些老系统上无效
* -k 当由pathname指定的文件或目录存在并且设置了“粘滞”位时返回真
* -p 当file存在并且是命令管道时返回为真
* -r 当由pathname指定的文件或目录存在并且可读时返回为真
* -s 当file存在文件大小大于0时返回真
* -u 当由pathname指定的文件或目录存在并且设置了SUID位时返回真
* -w 当由pathname指定的文件或目录存在并且可执行时返回真。一个目录为了它的内容被访问必然是可执行的。
* -o 当由pathname指定的文件或目录存在并且被子当前进程的有效用户ID所指定的用户拥有时返回真。
UNIX Shell 里面比较字符写法:
* -eq 等于
* -ne 不等于
* -gt 大于
* -lt 小于
* -le 小于等于
* -ge 大于等于
* -z 空串
* = 两个字符相等
* != 两个字符不等
* -n 非空串
<?php
function change($num)
{
$num_zero_result=2;
if($num==1)
return 1;
if($num==2)
return 2;
for($i=1;$i<$num-1;$i++)
{
$num_zero_result=$num_zero_result*2;
}
return $num_zero_result;
}
echo change(1);
echo change(2);
echo change(3);
echo change(4);
echo change(5);
echo change(6);
echo change(7);
echo change(8);
echo change(9);
?>
function change($num)
{
$num_zero_result=2;
if($num==1)
return 1;
if($num==2)
return 2;
for($i=1;$i<$num-1;$i++)
{
$num_zero_result=$num_zero_result*2;
}
return $num_zero_result;
}
echo change(1);
echo change(2);
echo change(3);
echo change(4);
echo change(5);
echo change(6);
echo change(7);
echo change(8);
echo change(9);
?>
写了个api,被人调用,coresearch_get_del2.php?type=deluser&uid=1456736567 发现有人用如下方式调用:
coresearch_get_del2.php?type=deluser&uid=
为空,于是本人用isset来判断失败了,最后修改为:
if(!strlen(trim($uid)))
{
echo "trim space has no number";
exit(0);
}
最好修改为:
if(empty($uid))
{
echo "trim space find has no number,is empty?";
exit(0);
}
看看区别url:
http://www.g168.net/html/PHP_006/2007/1216/20076531760459.html
Empty函数:
一)无论是Null还是真的是空:'' 用empty都能正确判断返回1值:
---------- 调试PHP ----------
11
输出完成 (耗时 0 秒) - 正常终止
二)对连接Memcache里没有值的情况其返回为false值,用empty也能判断:
---------- 调试PHP ----------
Get key1 value: This is first value
bool(false)
bool(true)
输出完成 (耗时 0 秒) - 正常终止
总之,empty函数对真的空,Null,及bool的false都能判断正确。
网上:empty:
如果 变量 是非空或非零的值,则 empty() 返回 FALSE。换句话说,""、0、"0"、NULL、FALSE、array()、var $var、未定义; 以及没有任何属性的对象都将被认为是空的,如果 var 为空,则返回 TRUE。
来自:http://www.cnblogs.com/chengmo/archive/2010/10/18/1854258.html
coresearch_get_del2.php?type=deluser&uid=
为空,于是本人用isset来判断失败了,最后修改为:
if(!strlen(trim($uid)))
{
echo "trim space has no number";
exit(0);
}
最好修改为:
if(empty($uid))
{
echo "trim space find has no number,is empty?";
exit(0);
}
看看区别url:
http://www.g168.net/html/PHP_006/2007/1216/20076531760459.html
Empty函数:
一)无论是Null还是真的是空:'' 用empty都能正确判断返回1值:
---------- 调试PHP ----------
11
输出完成 (耗时 0 秒) - 正常终止
二)对连接Memcache里没有值的情况其返回为false值,用empty也能判断:
---------- 调试PHP ----------
Get key1 value: This is first value
bool(false)
bool(true)
输出完成 (耗时 0 秒) - 正常终止
总之,empty函数对真的空,Null,及bool的false都能判断正确。
网上:empty:
如果 变量 是非空或非零的值,则 empty() 返回 FALSE。换句话说,""、0、"0"、NULL、FALSE、array()、var $var、未定义; 以及没有任何属性的对象都将被认为是空的,如果 var 为空,则返回 TRUE。
来自:http://www.cnblogs.com/chengmo/archive/2010/10/18/1854258.html
重启:
重启二:
关机一:
关机二:
[root@localhost ~]# init 0 //关机
[root@localhost ~]# init 1 //切换到单用户模式/救援模式
[root@localhost ~]# init 2 //切换到无网络连接的多用户命令行模式
[root@localhost ~]# init 3 //切换到有网络连接的多用户命令行模式
[root@localhost ~]# init 4 //不可用
[root@localhost ~]# init 5 //切换到带图形界面的多用户模式
[root@localhost ~]# init 6 //重启
本文出自:LinuxAid.com.cn 作者: sword_martin (2002-01-30 21:03:06)
在linux下一些常用的关机/重启命令有shutdown、halt、reboot、及init,它们都
可以达到重启系统的目的,但每个命令的内部工作过程是不同的,通过本文的介绍,希
望你可以更加灵活的运用各种关机命令。
1.shutdown
shutdown命令安全地将系统关机。 有些用户会使用直接断掉电源的方式来关闭linux,
这是十分危险的。因为linux与windows不同,其后台运行着许多进程,所以强制关机可能
会导致进程的数据丢失﹐使系统处于不稳定的状态﹐甚至在有的系统中会损坏硬件设备。
而在系统关机前使用shutdown命令﹐系统管理员会通知所有登录的用户系统将要关闭。
并且login指令会被冻结﹐即新的用户不能再登录。直接关机或者延迟一定的时间才关机
都是可能的﹐还可能重启。这是由所有进程〔process〕都会收到系统所送达的信号〔signal〕
决定的。这让像vi之类的程序有时间储存目前正在编辑的文档﹐而像处理邮件〔mail〕和
新闻〔news〕的程序则可以正常地离开等等。
shutdown执行它的工作是送信号〔signal〕给init程序﹐要求它改变runlevel。
Runlevel 0被用来停机〔halt〕﹐runlevel 6是用来重新激活〔reboot〕系统﹐
而runlevel 1则是被用来让系统进入管理工作可以进行的状态﹔这是预设的﹐假定没有-h也
没有-r参数给shutdown。要想了解在停机〔halt〕或者重新开机〔reboot〕过程中做了哪些
动作﹐你可以在这个文件/etc/inittab里看到这些runlevels相关的资料。
shutdown 参数说明:
[-t] 在改变到其它runlevel之前﹐告诉init多久以后关机。
[-r] 重启计算器。
[-k] 并不真正关机﹐只是送警告信号给每位登录者〔login〕。
[-h] 关机后关闭电源〔halt〕。
[-n] 不用init﹐而是自己来关机。不鼓励使用这个选项﹐而且该选项所产生的后果往
往不总是你所预期得到的。
[-c] cancel current process取消目前正在执行的关机程序。所以这个选项当然没有
时间参数﹐但是可以输入一个用来解释的讯息﹐而这信息将会送到每位使用者。
[-f] 在重启计算器〔reboot〕时忽略fsck。
[-F] 在重启计算器〔reboot〕时强迫fsck。
[-time] 设定关机〔shutdown〕前的时间。
2.halt----最简单的关机命令
其实halt就是调用shutdown -h。halt执行时﹐杀死应用进程﹐执行sync系统调用﹐
文件系统写操作完成后就会停止内核。
参数说明:
[-n] 防止sync系统调用﹐它用在用fsck修补根分区之后﹐以阻止内核用老版本的超
级块〔superblock〕覆盖修补过的超级块。
[-w] 并不是真正的重启或关机﹐只是写wtmp〔/var/log/wtmp〕纪录。
[-d] 不写wtmp纪录〔已包含在选项[-n]中〕。
[-f] 没有调用shutdown而强制关机或重启。
[-i] 关机〔或重启〕前﹐关掉所有的网络接口。
[-p] 该选项为缺省选项。就是关机时调用poweroff。
3.reboot
reboot的工作过程差不多跟halt一样﹐不过它是引发主机重启﹐而halt是关机。它
的参数与halt相差不多。
4.init
init是所有进程的祖先﹐它的进程号始终为1﹐所以发送TERM信号给init会终止所有的
用户进程﹑守护进程等。shutdown 就是使用这种机制。init定义了8个运行级别(runlevel),
init 0为关机﹐init 1为重启。关于init可以长篇大论﹐这里就不再叙述。另外还有
telinit命令可以改变init的运行级别﹐比如﹐telinit -iS可使系统进入单用户模式﹐
并且得不到使用shutdown时的信息和等待时间。
1关机命令 shutdown
好像ubuntu的终端中默认的是当前用户的命令,只是普通用户,因此在终端器中可以使用sudo -sh 转换到管理员root用户下执行命令。
1)shutdown --help
可以查看shutdown命令如何使用,当然也可以使用man shutdown命令。
2) shutdown -h now 现在立即关机
3)shutdown -r now 现在立即重启 , 或者 init 6 //重启 init 1是单用户级别, Init6才 是重新启动。
4)shutdown -r +3 三分钟后重启
5)shutdown -h +3 "The System will shutdown after 3 minutes" 提示使用者将在三分钟后关机
6)shutdown -r 20:23 在20:23时将重启计算机
7)shutdown -r 20:23 & 可以将在20:23时重启的任务放到后台去,用户可以继续操作终端
2中断命令
1)执行完命令后(若没有转到后台),可以使用CTRL+C来中止命令
2)kill 程序编码
当命令在后台执行时系统会返回一个程序编码,例如:在使用 shutdown -r 20:23 & 系统返回系统编码:4905
我们可以使用kill 4905来中止重启命令
3ps aux | grep 程序编号
我们如果知道程序的编号,我们可以使用ps aux |grep 程序编号来查询该程序编号对应的命令是什么。
例如上面的程序编号为4905 ,我们可以使用ps aux | grep 4905 就可以查到 shutdown -r 20:23 & 的命令
halt—-最简单的关机命令
其实halt就是调用shutdown -h。halt执行时﹐杀死应用进程﹐执行sync系统调用﹐文件系统写操作完成后就会停止内核。
参数说明:
[-n] 防止sync系统调用﹐它用在用fsck修补根分区之后﹐以阻止内核用老版本的超级块〔superblock〕覆盖修补过的超级块。
[-w] 并不是真正的重启或关机﹐只是写wtmp〔/var/log/wtmp〕纪录。
[-d] 不写wtmp纪录〔已包含在选项[-n]中〕。
[-f] 没有调用shutdown而强制关机或重启。
[-i] 关机〔或重启〕前﹐关掉所有的网络接口。
[-p] 该选项为缺省选项。就是关机时调用poweroff。
init
init是所有进程的祖先﹐它的进程号始终为1﹐所以发送TERM信号给init会终止所有的用户进程﹑守护进程等。shutdown 就是使用这种机制。init定义了8个运行级别(runlevel),init 0为关机﹐init 1为重启。关于init可以长篇大论﹐这里就不再叙述。另外还有telinit命令可以改变init的运行级别﹐比如﹐telinit -iS可使系统进入单用户模式﹐并且得不到使用shutdown时的信息和等待时间。
注销系统的logout命令
Logout 注销是登陆的相对操作,登陆系统后,若要离开系统,用户只要直接下达logout命令即可:
[root@localhost root]#logout
Red Hat Linuxrelease 9(Shike)
Kernel 2.4.20.8 on an i686
Login: ← 回到登陆的画面
重启二:
关机一:
关机二:
[root@localhost ~]# init 0 //关机
[root@localhost ~]# init 1 //切换到单用户模式/救援模式
[root@localhost ~]# init 2 //切换到无网络连接的多用户命令行模式
[root@localhost ~]# init 3 //切换到有网络连接的多用户命令行模式
[root@localhost ~]# init 4 //不可用
[root@localhost ~]# init 5 //切换到带图形界面的多用户模式
[root@localhost ~]# init 6 //重启
本文出自:LinuxAid.com.cn 作者: sword_martin (2002-01-30 21:03:06)
在linux下一些常用的关机/重启命令有shutdown、halt、reboot、及init,它们都
可以达到重启系统的目的,但每个命令的内部工作过程是不同的,通过本文的介绍,希
望你可以更加灵活的运用各种关机命令。
1.shutdown
shutdown命令安全地将系统关机。 有些用户会使用直接断掉电源的方式来关闭linux,
这是十分危险的。因为linux与windows不同,其后台运行着许多进程,所以强制关机可能
会导致进程的数据丢失﹐使系统处于不稳定的状态﹐甚至在有的系统中会损坏硬件设备。
而在系统关机前使用shutdown命令﹐系统管理员会通知所有登录的用户系统将要关闭。
并且login指令会被冻结﹐即新的用户不能再登录。直接关机或者延迟一定的时间才关机
都是可能的﹐还可能重启。这是由所有进程〔process〕都会收到系统所送达的信号〔signal〕
决定的。这让像vi之类的程序有时间储存目前正在编辑的文档﹐而像处理邮件〔mail〕和
新闻〔news〕的程序则可以正常地离开等等。
shutdown执行它的工作是送信号〔signal〕给init程序﹐要求它改变runlevel。
Runlevel 0被用来停机〔halt〕﹐runlevel 6是用来重新激活〔reboot〕系统﹐
而runlevel 1则是被用来让系统进入管理工作可以进行的状态﹔这是预设的﹐假定没有-h也
没有-r参数给shutdown。要想了解在停机〔halt〕或者重新开机〔reboot〕过程中做了哪些
动作﹐你可以在这个文件/etc/inittab里看到这些runlevels相关的资料。
shutdown 参数说明:
[-t] 在改变到其它runlevel之前﹐告诉init多久以后关机。
[-r] 重启计算器。
[-k] 并不真正关机﹐只是送警告信号给每位登录者〔login〕。
[-h] 关机后关闭电源〔halt〕。
[-n] 不用init﹐而是自己来关机。不鼓励使用这个选项﹐而且该选项所产生的后果往
往不总是你所预期得到的。
[-c] cancel current process取消目前正在执行的关机程序。所以这个选项当然没有
时间参数﹐但是可以输入一个用来解释的讯息﹐而这信息将会送到每位使用者。
[-f] 在重启计算器〔reboot〕时忽略fsck。
[-F] 在重启计算器〔reboot〕时强迫fsck。
[-time] 设定关机〔shutdown〕前的时间。
2.halt----最简单的关机命令
其实halt就是调用shutdown -h。halt执行时﹐杀死应用进程﹐执行sync系统调用﹐
文件系统写操作完成后就会停止内核。
参数说明:
[-n] 防止sync系统调用﹐它用在用fsck修补根分区之后﹐以阻止内核用老版本的超
级块〔superblock〕覆盖修补过的超级块。
[-w] 并不是真正的重启或关机﹐只是写wtmp〔/var/log/wtmp〕纪录。
[-d] 不写wtmp纪录〔已包含在选项[-n]中〕。
[-f] 没有调用shutdown而强制关机或重启。
[-i] 关机〔或重启〕前﹐关掉所有的网络接口。
[-p] 该选项为缺省选项。就是关机时调用poweroff。
3.reboot
reboot的工作过程差不多跟halt一样﹐不过它是引发主机重启﹐而halt是关机。它
的参数与halt相差不多。
4.init
init是所有进程的祖先﹐它的进程号始终为1﹐所以发送TERM信号给init会终止所有的
用户进程﹑守护进程等。shutdown 就是使用这种机制。init定义了8个运行级别(runlevel),
init 0为关机﹐init 1为重启。关于init可以长篇大论﹐这里就不再叙述。另外还有
telinit命令可以改变init的运行级别﹐比如﹐telinit -iS可使系统进入单用户模式﹐
并且得不到使用shutdown时的信息和等待时间。
1关机命令 shutdown
好像ubuntu的终端中默认的是当前用户的命令,只是普通用户,因此在终端器中可以使用sudo -sh 转换到管理员root用户下执行命令。
1)shutdown --help
可以查看shutdown命令如何使用,当然也可以使用man shutdown命令。
2) shutdown -h now 现在立即关机
3)shutdown -r now 现在立即重启 , 或者 init 6 //重启 init 1是单用户级别, Init6才 是重新启动。
4)shutdown -r +3 三分钟后重启
5)shutdown -h +3 "The System will shutdown after 3 minutes" 提示使用者将在三分钟后关机
6)shutdown -r 20:23 在20:23时将重启计算机
7)shutdown -r 20:23 & 可以将在20:23时重启的任务放到后台去,用户可以继续操作终端
2中断命令
1)执行完命令后(若没有转到后台),可以使用CTRL+C来中止命令
2)kill 程序编码
当命令在后台执行时系统会返回一个程序编码,例如:在使用 shutdown -r 20:23 & 系统返回系统编码:4905
我们可以使用kill 4905来中止重启命令
3ps aux | grep 程序编号
我们如果知道程序的编号,我们可以使用ps aux |grep 程序编号来查询该程序编号对应的命令是什么。
例如上面的程序编号为4905 ,我们可以使用ps aux | grep 4905 就可以查到 shutdown -r 20:23 & 的命令
halt—-最简单的关机命令
其实halt就是调用shutdown -h。halt执行时﹐杀死应用进程﹐执行sync系统调用﹐文件系统写操作完成后就会停止内核。
参数说明:
[-n] 防止sync系统调用﹐它用在用fsck修补根分区之后﹐以阻止内核用老版本的超级块〔superblock〕覆盖修补过的超级块。
[-w] 并不是真正的重启或关机﹐只是写wtmp〔/var/log/wtmp〕纪录。
[-d] 不写wtmp纪录〔已包含在选项[-n]中〕。
[-f] 没有调用shutdown而强制关机或重启。
[-i] 关机〔或重启〕前﹐关掉所有的网络接口。
[-p] 该选项为缺省选项。就是关机时调用poweroff。
init
init是所有进程的祖先﹐它的进程号始终为1﹐所以发送TERM信号给init会终止所有的用户进程﹑守护进程等。shutdown 就是使用这种机制。init定义了8个运行级别(runlevel),init 0为关机﹐init 1为重启。关于init可以长篇大论﹐这里就不再叙述。另外还有telinit命令可以改变init的运行级别﹐比如﹐telinit -iS可使系统进入单用户模式﹐并且得不到使用shutdown时的信息和等待时间。
注销系统的logout命令
Logout 注销是登陆的相对操作,登陆系统后,若要离开系统,用户只要直接下达logout命令即可:
[root@localhost root]#logout
Red Hat Linuxrelease 9(Shike)
Kernel 2.4.20.8 on an i686
Login: ← 回到登陆的画面
由于要作项目开发,考虑到就几个人同时开发,于是想用下CVS
CVS ---Concurrent Versions system(并发版本管理系统)是一个版本控制管理系统,他是目前最为广泛使用的一个系统.大家只要曾经下载过linux的软件源代码(比如tar.gz的文件)你可以在没一个目录下看到CVS目录,那就说明他的软件是CVS进行控制的.
目前基本上流行的Linux发布版本都自带有cvs.
CVS初始化
---------------------------------
----------------------------------
环境设置:指定CVS库的路径CVSROOT
tcsh中设置
setenv CVSROOT /yourpath
bash中设置
export CVSROOT=/yourpath
初始化:
%cvs init
这时会在你的$CVSROOT目录下产生CVSROOT目录,下面是他生成的一些文件.
尽量不要去改变他.
一个项目的导入:
现在把我们的项目导入到CVS中去
%cvs import -m "your comment message" yourprojectname vendor_tag release_tag
执行后,会把当前目录下的所有文件(包括子目录)导入到/yourpath/yourprojectname目录中去
vender_tag:开发伤标记
release_tag:版本发布标记
现在你可以删去原来的源代码了.
ok,现在可以使用CVS了,找到一个合适的目录执行
%cvs checkout project_name
cvs将创建project_name目录,并将最新版本的源代码导出到相应的目录中.
CVS的基本使用
----------------------------------
----------------------------------
当你执行过cvs checkout,就不要来再次导出了,以后只要使用
%cvs update
来同步文件,如果连带子目录也要同步,就必需使用
%cvs update -d 了.
添加文件:
当你新写了一个文件后,可以使用
%cvs add filename来提交
这时其实文件并没有真正的提交,\如果要确定提交,使用下面的命令
%cvs commit -m "your comment"
删除文件:
%cvs rm filename
%cvs commit -m "why delete this file(s)"
导出发布不代CVS目录的源代码
如果系统完成了,需要发布,使用cvs export命令,不过export只是针对一个TAG或者日期导出,可以是这些命令方式:
%cvs export -r release1 project_name
%cvs export -D 20040303 project_name
%cvs export -D now project_name
对于cvs client端,如果使用linux,则已经有了,如果是windows,就使用wincvs吧.
这里要考虑到cvs的远程认证,我们使用cvs本身的pserver的认证方式
首先在服务器端建立启动文件
#cd /etc/xinted.d/
#cat cvsperver
# default: off
service cvspserver
{
disable = no
port = 2401
socket_type = stream
wait = no
#only_from = 127.0.0.1
user = apache
server = /usr/bin/cvs
passenv =/wpm-source/CVSROOT/passwd
server_args =-f --allow-root=/wpm-source pserver
log_on_failure += USERID
}
重新启动xinted
#kill -HUP xinted
然后进入你的$CVSROOT/CVSROOT目录,要建立passwd文件
这个文件的格式是
username:password:map_system_user
其中密码加密方式和apache中的加密方式一样,于是我们可以这样作:
#htpasswd -c passwd yourname
#cat passwd
yourname:sEylx9?G:apache
注意passwd文件后面的passwd是后来手工加入的.
如果你觉得这样麻烦,你可以使用cvstrac来管理.
cvstrac可以在
http://www.cvstrac.org
下载,我使用了,暂时还没有发现他的好处.
在客户端使用下面的命令来将项目导出
%cvs -d :pserver:yourname@yourip(or hostanme)#port/yourcvsroot checkout yourprojectname
这样就会在当前目录下建立yourprojectname的目录了.
现在你就可以在这个目录下做你的工作了.做完后,使用cvs基本使用中提到的命令来修改,更新和添加文件,就象在本地使用一样.
你最好设立这样的环境变量,这样下次开机就不要输入重复的命令
在/etc/profile文件中加入这样两行
CVSROOT=:pserver:yourname@cvsrootipaddress#port/cvsroot
export CVSROOT
就可以了.
使用感想: 阅读全文
CVS ---Concurrent Versions system(并发版本管理系统)是一个版本控制管理系统,他是目前最为广泛使用的一个系统.大家只要曾经下载过linux的软件源代码(比如tar.gz的文件)你可以在没一个目录下看到CVS目录,那就说明他的软件是CVS进行控制的.
目前基本上流行的Linux发布版本都自带有cvs.
CVS初始化
---------------------------------
----------------------------------
环境设置:指定CVS库的路径CVSROOT
tcsh中设置
setenv CVSROOT /yourpath
bash中设置
export CVSROOT=/yourpath
初始化:
%cvs init
这时会在你的$CVSROOT目录下产生CVSROOT目录,下面是他生成的一些文件.
尽量不要去改变他.
一个项目的导入:
现在把我们的项目导入到CVS中去
%cvs import -m "your comment message" yourprojectname vendor_tag release_tag
执行后,会把当前目录下的所有文件(包括子目录)导入到/yourpath/yourprojectname目录中去
vender_tag:开发伤标记
release_tag:版本发布标记
现在你可以删去原来的源代码了.
ok,现在可以使用CVS了,找到一个合适的目录执行
%cvs checkout project_name
cvs将创建project_name目录,并将最新版本的源代码导出到相应的目录中.
CVS的基本使用
----------------------------------
----------------------------------
当你执行过cvs checkout,就不要来再次导出了,以后只要使用
%cvs update
来同步文件,如果连带子目录也要同步,就必需使用
%cvs update -d 了.
添加文件:
当你新写了一个文件后,可以使用
%cvs add filename来提交
这时其实文件并没有真正的提交,\如果要确定提交,使用下面的命令
%cvs commit -m "your comment"
删除文件:
%cvs rm filename
%cvs commit -m "why delete this file(s)"
导出发布不代CVS目录的源代码
如果系统完成了,需要发布,使用cvs export命令,不过export只是针对一个TAG或者日期导出,可以是这些命令方式:
%cvs export -r release1 project_name
%cvs export -D 20040303 project_name
%cvs export -D now project_name
对于cvs client端,如果使用linux,则已经有了,如果是windows,就使用wincvs吧.
这里要考虑到cvs的远程认证,我们使用cvs本身的pserver的认证方式
首先在服务器端建立启动文件
#cd /etc/xinted.d/
#cat cvsperver
# default: off
service cvspserver
{
disable = no
port = 2401
socket_type = stream
wait = no
#only_from = 127.0.0.1
user = apache
server = /usr/bin/cvs
passenv =/wpm-source/CVSROOT/passwd
server_args =-f --allow-root=/wpm-source pserver
log_on_failure += USERID
}
重新启动xinted
#kill -HUP xinted
然后进入你的$CVSROOT/CVSROOT目录,要建立passwd文件
这个文件的格式是
username:password:map_system_user
其中密码加密方式和apache中的加密方式一样,于是我们可以这样作:
#htpasswd -c passwd yourname
#cat passwd
yourname:sEylx9?G:apache
注意passwd文件后面的passwd是后来手工加入的.
如果你觉得这样麻烦,你可以使用cvstrac来管理.
cvstrac可以在
http://www.cvstrac.org
下载,我使用了,暂时还没有发现他的好处.
在客户端使用下面的命令来将项目导出
%cvs -d :pserver:yourname@yourip(or hostanme)#port/yourcvsroot checkout yourprojectname
这样就会在当前目录下建立yourprojectname的目录了.
现在你就可以在这个目录下做你的工作了.做完后,使用cvs基本使用中提到的命令来修改,更新和添加文件,就象在本地使用一样.
你最好设立这样的环境变量,这样下次开机就不要输入重复的命令
在/etc/profile文件中加入这样两行
CVSROOT=:pserver:yourname@cvsrootipaddress#port/cvsroot
export CVSROOT
就可以了.
使用感想: 阅读全文
在许多Web编程里,字符串总是会被大量地生成和处理的。正确地使用和处理字符串,对于PHP程
序员来说也同样越来越重要了。本文从最简单的字符串定义一直引导你到高层字符串处理技巧,希望
对大家有所帮助。
一、引号定义字符串
在PHP中,通常一个字符串被定义在一对引号中,如:
'I am a string in single quotes'
"I am a string in double quotes"
PHP语法分析器是用成对的引号来判断一个字符串的。因此,所有字符串必须使用同一种单或者双
引号来定义开始和结束。例如,下面的字串定义是不合法的:
"I am not a valid string since I have unmatching quote marks'
'Me neither!"
定义字符串时,只有一种引号被视为定义符,即单引号或双引号。于是,如果一个字符串由双引
号开始,那么只有双引号被分析器解析。这样,你就可以在双引号串中包含任何其他字符,甚至单引
号。下面的引号串都是合法的:
$s = "I am a 'single quote string' inside a double quote string";
$s = 'I am a "double quote string" inside a single quote string';
当PHP遇到与串的开头相对应的引号时,便认为已经到了字符串尾部,于是:
"Why doesn't "this" work?" 阅读全文
序员来说也同样越来越重要了。本文从最简单的字符串定义一直引导你到高层字符串处理技巧,希望
对大家有所帮助。
一、引号定义字符串
在PHP中,通常一个字符串被定义在一对引号中,如:
'I am a string in single quotes'
"I am a string in double quotes"
PHP语法分析器是用成对的引号来判断一个字符串的。因此,所有字符串必须使用同一种单或者双
引号来定义开始和结束。例如,下面的字串定义是不合法的:
"I am not a valid string since I have unmatching quote marks'
'Me neither!"
定义字符串时,只有一种引号被视为定义符,即单引号或双引号。于是,如果一个字符串由双引
号开始,那么只有双引号被分析器解析。这样,你就可以在双引号串中包含任何其他字符,甚至单引
号。下面的引号串都是合法的:
$s = "I am a 'single quote string' inside a double quote string";
$s = 'I am a "double quote string" inside a single quote string';
当PHP遇到与串的开头相对应的引号时,便认为已经到了字符串尾部,于是:
"Why doesn't "this" work?" 阅读全文
前段时间有人问关于C++的继承与多态的问题,当时一边调试一边讲解也算是解释通了,但后来又有朋友问起此问题,便想写点这方面的东西,问题是这样的:
#include<iostream.h>
class base
{
public:
func()
{
cout<<”this is base class”<<endl;
}
};
class x: public base
{
public:
func()
{
cout<<”this is x class”<<endl;
}
};
void main()
{
base* p=new x;
p->func();
}
就是这样一个程序,得到的结果是什么呢?答案是:”this is base class”,而问题就在于这一句话:base* p=new x,程序的本意可能是要创建一个x 的对象,但为什么执行的是base的func呢?我们先来看一下new用法,new的作用在堆里为象分配内存并为这块内存调用构造函数,并且内置了长度计算,类型转换和安全检查,通用的格式是Type *p=new Type,而在程序中使用的是base* p=new x,这样就产生了第一个问题,p到底是指向base还是指向x,按照通用的格式应该指向Type,但到底是前面的Type还是后面的Type呢?于是我便把base* p=new x 改成了x* p=new base结果出错,编译器提示不能把类型base转变成x,看来当前一个Type和后一个Type的型类不一致是会发生类型转换,正好new的内置功能里带用类型转换,不难看出这里是把第二个Type转换成第一个Type,但为什么当把base转换成x时会出误错呢?这里就引出了个上向类型转换的概念,所谓上向类型转换就是取一个对象的地址,并将其作为基类的地址一处理,也就是说只能由子类向父类转换.综合上面的解释,程序中实际上是创建了一个base类型的对象,为了证明的我结论是正确的,我又作了以下调式,在base类中添加一个函数a,在x中添加了一函数b,因为x是继承base.所以如果p是x的话那么它可以调用父类的函数a,也可以调用x类的函数b,反之则只能调到base类的函数a,而不能调用x的函数b,调式发现,结果和我想像的是相符合的,也证明了以上的结论.
其实到这里只是完成了整个问题的第一步,于是继续修改程序:
我把程序改成:
#include<iostream.h>
class base
{
public:
virtual func()
{
cout<<”this is base class”<<endl;
}
};
class x: public base
{
public:
func()
{
cout<<”this is x class”<<endl;
}
};
void main()
{
base* p=new x;
p->func();
}
这种里的修改是把func改成了虚函数,再执行,结果是:”this is x class”,这个结果似乎有点出乎意料,似乎和我第一步的结论相反,但第一步是论证是比较严谨的,于是我把注意力集中到了虚函数上.要找到本质原因,还得从虚函数的现实讲起,我们来看一下虚函数是怎样实现的,
把程序改成:
#include<iostream.h>
class base
{
public:
virtual func()
{
cout<<”this is base class”<<endl;
}
};
class x: public base
{
public:
func()
{
cout<<”this is x class”<<endl;
}
};
void main()
{
x* p=new x;
p->func();
}
注意,这里主要改的是x* p=new x,建一个x对象,则由于func函数是一个虚函数,所在这里应该调用的是x的func而当func不是虚函数时,则调用base的func函数,虚函数和普通函数到底有什么区别?编译器又是怎么处理的?我们来作一个测式,写如下程序:
#include <iostream.h>
class X{
int i;
public:
a()
{
}
};
class Y{
int i;
public:
virtual a()
{
}
};
class Z{
int i;
public:
virtual a()
{
}
virtual b()
{
}
};
void main()
{
cout<<sizeof(X)<<endl;
cout<<sizeof(Y)<<endl;
cout<<sizeof(Z)<<endl;
}
这样我们可以得到三个类的大小,分别是:4,8,8类X与类Y的构构基本相同但Y的大小是X的两倍,而X与Y的不同点就是Y的a是一个虚函数,而Y与Z的大小是相同的,但Z有两个虚函数,而Y只是一个虚函数,得出这样的结果的原因是因为不带虚函数的对象的长度是单个int的长度,而带有单个虚函数的对象长度是不带虚函数的长度再加上一个指针的长度,实际是编译器在Y中插入了一个指针(VPTR),所以带一个虚函数和带两个虚函数没有区别,都只插入了一个指针,而这个指针指向一个存放函数地址的表(虚函数据表),这个表存放着具体函数。我们用函数图来画出函数的结构:
难点就在于虚函数表的内容是依据类中的虚函数声明次序,一一填入函数指针,子类会继承父类的虚函数表,当我们在改写子类时,虚函数表就受了影响:表中元素指的函数地址不再是父类的函数地址,而是子类的函数地址。所以当我们创建一个X对像的时候,编译器能知道执行的是X的func
我们再来看:base* p=new X
前面我们讲了这里是按照向上类型转换的原则把X转换成了base,而此时baser的VPTR指针会指向X的虚函数表,所以,p->func()会执行X的func函数.
#include<iostream.h>
class base
{
public:
func()
{
cout<<”this is base class”<<endl;
}
};
class x: public base
{
public:
func()
{
cout<<”this is x class”<<endl;
}
};
void main()
{
base* p=new x;
p->func();
}
就是这样一个程序,得到的结果是什么呢?答案是:”this is base class”,而问题就在于这一句话:base* p=new x,程序的本意可能是要创建一个x 的对象,但为什么执行的是base的func呢?我们先来看一下new用法,new的作用在堆里为象分配内存并为这块内存调用构造函数,并且内置了长度计算,类型转换和安全检查,通用的格式是Type *p=new Type,而在程序中使用的是base* p=new x,这样就产生了第一个问题,p到底是指向base还是指向x,按照通用的格式应该指向Type,但到底是前面的Type还是后面的Type呢?于是我便把base* p=new x 改成了x* p=new base结果出错,编译器提示不能把类型base转变成x,看来当前一个Type和后一个Type的型类不一致是会发生类型转换,正好new的内置功能里带用类型转换,不难看出这里是把第二个Type转换成第一个Type,但为什么当把base转换成x时会出误错呢?这里就引出了个上向类型转换的概念,所谓上向类型转换就是取一个对象的地址,并将其作为基类的地址一处理,也就是说只能由子类向父类转换.综合上面的解释,程序中实际上是创建了一个base类型的对象,为了证明的我结论是正确的,我又作了以下调式,在base类中添加一个函数a,在x中添加了一函数b,因为x是继承base.所以如果p是x的话那么它可以调用父类的函数a,也可以调用x类的函数b,反之则只能调到base类的函数a,而不能调用x的函数b,调式发现,结果和我想像的是相符合的,也证明了以上的结论.
其实到这里只是完成了整个问题的第一步,于是继续修改程序:
我把程序改成:
#include<iostream.h>
class base
{
public:
virtual func()
{
cout<<”this is base class”<<endl;
}
};
class x: public base
{
public:
func()
{
cout<<”this is x class”<<endl;
}
};
void main()
{
base* p=new x;
p->func();
}
这种里的修改是把func改成了虚函数,再执行,结果是:”this is x class”,这个结果似乎有点出乎意料,似乎和我第一步的结论相反,但第一步是论证是比较严谨的,于是我把注意力集中到了虚函数上.要找到本质原因,还得从虚函数的现实讲起,我们来看一下虚函数是怎样实现的,
把程序改成:
#include<iostream.h>
class base
{
public:
virtual func()
{
cout<<”this is base class”<<endl;
}
};
class x: public base
{
public:
func()
{
cout<<”this is x class”<<endl;
}
};
void main()
{
x* p=new x;
p->func();
}
注意,这里主要改的是x* p=new x,建一个x对象,则由于func函数是一个虚函数,所在这里应该调用的是x的func而当func不是虚函数时,则调用base的func函数,虚函数和普通函数到底有什么区别?编译器又是怎么处理的?我们来作一个测式,写如下程序:
#include <iostream.h>
class X{
int i;
public:
a()
{
}
};
class Y{
int i;
public:
virtual a()
{
}
};
class Z{
int i;
public:
virtual a()
{
}
virtual b()
{
}
};
void main()
{
cout<<sizeof(X)<<endl;
cout<<sizeof(Y)<<endl;
cout<<sizeof(Z)<<endl;
}
这样我们可以得到三个类的大小,分别是:4,8,8类X与类Y的构构基本相同但Y的大小是X的两倍,而X与Y的不同点就是Y的a是一个虚函数,而Y与Z的大小是相同的,但Z有两个虚函数,而Y只是一个虚函数,得出这样的结果的原因是因为不带虚函数的对象的长度是单个int的长度,而带有单个虚函数的对象长度是不带虚函数的长度再加上一个指针的长度,实际是编译器在Y中插入了一个指针(VPTR),所以带一个虚函数和带两个虚函数没有区别,都只插入了一个指针,而这个指针指向一个存放函数地址的表(虚函数据表),这个表存放着具体函数。我们用函数图来画出函数的结构:
难点就在于虚函数表的内容是依据类中的虚函数声明次序,一一填入函数指针,子类会继承父类的虚函数表,当我们在改写子类时,虚函数表就受了影响:表中元素指的函数地址不再是父类的函数地址,而是子类的函数地址。所以当我们创建一个X对像的时候,编译器能知道执行的是X的func
我们再来看:base* p=new X
前面我们讲了这里是按照向上类型转换的原则把X转换成了base,而此时baser的VPTR指针会指向X的虚函数表,所以,p->func()会执行X的func函数.
这不是最新的文章,但绝对称得上经典,耐心看完后你会有所收获!
转自“蓝森林”网站
原作者迪-克斯莫(Roberto Di Cosmo)博士的网站
[译者按]本文是在法国互联网上流传很广的对微软的檄文,作者是计算机博士,现就职于法国巴黎第七大学计算机系。原文已经被翻译成英语、德语、西班牙语和意大利语,可以在http://www.pps.jussieu.fr/~dicosmo/找到。
一、引言
圣诞前期间,我再次被媒界铺天盖地的报道所震惊。“多媒体”、“万维网”、“互联网”这些时髦词汇及其派生物如雨后春笋充人耳目。在这些报纸、杂志和那些即兴“专家”眼里,您如果手里没有一台崭新的、价钱昂贵的、能把您带入那五彩缤纷的虚拟空间的计算机,您就不算是个幸福的人。
我们时刻都在听着一个永恒不变的教导:世界上只有一种计算机,它叫PC,当然一定是安装着Intel芯片的PC,而且世界上只存在一个必不可少的软件-微软生产的Window系列(大家干脆懒得去区分“操作系统”和“应用软件”这两个截然不同的名词,媒界所说的Window97实际上就是Window95捆绑上word、Excel等办公软件,被称为Office97的东西)。
更令人奇怪的还在后头,今天美国人已经开始从漫长的冬眠里觉醒,意识到这两个超级跨国公司的阴险嘴脸:它们利用自己的垄断地位,扼杀了无数产品性能远远高于自己的公司。而我们法国却厚颜无耻的在向这两个托拉斯献媚争宠。我佩服Ralph Nader(勇敢的站出来保护消费者的利益,令美国通用汽车公司撤回它们生产的不安全汽车),佩服美国司法部对微软的起诉,更佩服美国民众对此事的强烈反响:美国著名的亲微软的CNN电视台在网上做了民意测验,结果绝大多数网民支持司法部的举动,CNN竟然中止了此项调查,在无数网民的抗议下,不得不公布结果。
但是法国的民众还沉睡在微软那温柔的摇篮里,他们梦见一个仁慈的善者在向所有的学校乡村分发免费的Window95,真心实意的帮助法国弥补技术上的落后;他们微笑着看着天蓝色的屏幕上显示出一条条令人安心的信息,告诉用户某某环节某某过程引起了某某例外,当然这只是您自己的操作不当,不是Window的错误;他们在这美梦里从来不反问一下:一个比几十年前能把人类送上月球又安全送回来时所用的计算机还强劲几倍、几十倍的PC,被安装上微软的Office97以后,为什么不能正确的处理一本只有百来页的资料? 阅读全文
转自“蓝森林”网站
原作者迪-克斯莫(Roberto Di Cosmo)博士的网站
[译者按]本文是在法国互联网上流传很广的对微软的檄文,作者是计算机博士,现就职于法国巴黎第七大学计算机系。原文已经被翻译成英语、德语、西班牙语和意大利语,可以在http://www.pps.jussieu.fr/~dicosmo/找到。
一、引言
圣诞前期间,我再次被媒界铺天盖地的报道所震惊。“多媒体”、“万维网”、“互联网”这些时髦词汇及其派生物如雨后春笋充人耳目。在这些报纸、杂志和那些即兴“专家”眼里,您如果手里没有一台崭新的、价钱昂贵的、能把您带入那五彩缤纷的虚拟空间的计算机,您就不算是个幸福的人。
我们时刻都在听着一个永恒不变的教导:世界上只有一种计算机,它叫PC,当然一定是安装着Intel芯片的PC,而且世界上只存在一个必不可少的软件-微软生产的Window系列(大家干脆懒得去区分“操作系统”和“应用软件”这两个截然不同的名词,媒界所说的Window97实际上就是Window95捆绑上word、Excel等办公软件,被称为Office97的东西)。
更令人奇怪的还在后头,今天美国人已经开始从漫长的冬眠里觉醒,意识到这两个超级跨国公司的阴险嘴脸:它们利用自己的垄断地位,扼杀了无数产品性能远远高于自己的公司。而我们法国却厚颜无耻的在向这两个托拉斯献媚争宠。我佩服Ralph Nader(勇敢的站出来保护消费者的利益,令美国通用汽车公司撤回它们生产的不安全汽车),佩服美国司法部对微软的起诉,更佩服美国民众对此事的强烈反响:美国著名的亲微软的CNN电视台在网上做了民意测验,结果绝大多数网民支持司法部的举动,CNN竟然中止了此项调查,在无数网民的抗议下,不得不公布结果。
但是法国的民众还沉睡在微软那温柔的摇篮里,他们梦见一个仁慈的善者在向所有的学校乡村分发免费的Window95,真心实意的帮助法国弥补技术上的落后;他们微笑着看着天蓝色的屏幕上显示出一条条令人安心的信息,告诉用户某某环节某某过程引起了某某例外,当然这只是您自己的操作不当,不是Window的错误;他们在这美梦里从来不反问一下:一个比几十年前能把人类送上月球又安全送回来时所用的计算机还强劲几倍、几十倍的PC,被安装上微软的Office97以后,为什么不能正确的处理一本只有百来页的资料? 阅读全文
[IE下的Firebug,微软开发的和Firefox下的IE插件]发现IE版firebug,最近又出了一个和firefox下的firebug一样的在IE上可以调试使用。
Php/Js/Shell/Go jackxiang 2008-7-5 18:38
一直在firefox下用firebug调试web UI,在IE下简直就是噩梦,njj发现了IE版的firebug Internet Explorer Developer Toolbar,立即告诉了我,IE下调试兼容页面的苦难日子终于过去了。
http://www.microsoft.com/downloads/details.aspx?FamilyID=e59c3964-672d-4511-bb3e-2d5e1db91038&DisplayLang=en
---------------------------------------------------------------------------------------------------------------------------------------------------------
这个工具的用法,我还在探索中……
和firefox下的firebug一样的在IE上可以使用:
http://www.cnblogs.com/hooray/archive/2011/04/21/2023289.html
---------------------------------------------------------------------------------------------------------------------------------------------------------
IE下使用firebug:
把下面这段代码复制到地址栏,然后运行即可。
firebug官网:https://getfirebug.com/
_______________________________________________________________________________________
Add Time: 2014-03-21 (下面都不是问题,用fiddler2直接加载进去即可,可以修改下高度,查看下样式足够了。)
如果你想让页面默认就有一个firebug的小按钮进行调试,那直接加一句:
<head>
...
<script type="text/javascript" src="https://getfirebug.com/firebug-lite.js"></script>
...
</head>
虽然现在能在IE是使用fb了,但是IE上的fb缺陷还是有的,比如html代码不会实时更新,尤其是在测试jquery插件的时候就无奈了。
不过总的来说,firebug for ie还是解决了我们在IE上检查样式及代码提供了一个很好的工具。
http://www.microsoft.com/downloads/details.aspx?FamilyID=e59c3964-672d-4511-bb3e-2d5e1db91038&DisplayLang=en
---------------------------------------------------------------------------------------------------------------------------------------------------------
这个工具的用法,我还在探索中……
和firefox下的firebug一样的在IE上可以使用:
http://www.cnblogs.com/hooray/archive/2011/04/21/2023289.html
---------------------------------------------------------------------------------------------------------------------------------------------------------
IE下使用firebug:
把下面这段代码复制到地址栏,然后运行即可。
firebug官网:https://getfirebug.com/
_______________________________________________________________________________________
Add Time: 2014-03-21 (下面都不是问题,用fiddler2直接加载进去即可,可以修改下高度,查看下样式足够了。)
如果你想让页面默认就有一个firebug的小按钮进行调试,那直接加一句:
<head>
...
<script type="text/javascript" src="https://getfirebug.com/firebug-lite.js"></script>
...
</head>
虽然现在能在IE是使用fb了,但是IE上的fb缺陷还是有的,比如html代码不会实时更新,尤其是在测试jquery插件的时候就无奈了。
不过总的来说,firebug for ie还是解决了我们在IE上检查样式及代码提供了一个很好的工具。
实现功能:当用户在本地客户端某目录内建立、修改、删除目录或文件、修改目录或文件的属性,只要执行相同的shell脚本,rsync就会自动找出有改动或删除的数据,将其传送到服务器上,使服务器端某目录内的数据跟本地客户端某目录内的数据保持一致。
★方式一:
一、服务器端(例:10.0.0.1*):
1、创建用户和组
groupadd www -g 48
useradd -u 48 -g www www
mkdir -p /opt/htdocs
chmod +w /opt/htdocs
chown www:www /opt/htdocs
2、编辑rsync的配置文件
vi /etc/rsyncd.conf
输入以下内容:
引用
uid=www
gid=www
max connections=10
use chroot=no
log file=/var/log/rsyncd.log
pid file=/var/run/rsyncd.pid
lock file=/var/run/rsyncd.lock
[zhangyan]
path=/opt/htdocs
comment = my htdocs
ignore errors
read only = no
hosts allow=10.0.0.21 10.0.0.22
3、启动rsync服务器端
/usr/bin/rsync --daemon
二、客户端(例:10.0.0.21和10.0.0.22):
1、创建一个shell脚本push.sh
vi push.sh
输入以下内容(10.0.0.1*为要推送到的目标服务器,zhangyan为服务器端rsyncd.conf配置文件中的模块名):
引用
#!/bin/sh
/usr/bin/rsync -vzrtopg --delete $1 10.0.0.10::zhangyan/
/usr/bin/rsync -vzrtopg --delete $1 10.0.0.11::zhangyan/
/usr/bin/rsync -vzrtopg --delete $1 10.0.0.16::zhangyan/
/usr/bin/rsync -vzrtopg --delete $1 10.0.0.19::zhangyan/
注:因为是内部局域网之间传输,这里没有设置密码。
2、赋予push.sh执行权限
chmod +x ./push.sh
3、同步推送客户端某个目录中(例:/home/zhanguan/abc)的文件到服务器端的/opt/htdocs目录:
./push.sh /home/zhanguan/abc/
注意:不要忘了abc后面的/。如果更改的文件太大,可以在上面语句的末尾加上空格和&号,推到后台执行。例:
./push.sh /home/zhanguan/abc/ &
★方式二:
一、服务器端(例:10.0.0.1*):
1、创建用户和组
groupadd www -g 48
useradd -u 48 -g www www
mkdir -p /opt/htdocs
chmod +w /opt/htdocs
chown www:www /opt/htdocs
passwd www
为www用户设置一个密码。
二、客户端:
1、同步推送客户端某个目录中(例:/home/zhanguan/abc)的文件到服务器端的/opt/htdocs目录:
/usr/bin/rsync -vzrtopg --delete /home/zhanguan/abc/ -e ssh www@10.0.0.10:/opt/htdocs/
输入密码,回车即可,无须服务器端启动rsync服务。
[ 2007-7-16 16:44 | by 张宴 ]
推送:
/usr/bin/rsync -avgt --progress --password-file=/usr/local/etc/rsyncd.secrets /data0/vshare/logs/user_search/iasks/* backupuser@219.142.118.48::boke_2008_sum_olympic_video
查看目录:
/usr/bin/rsync --password-file=/usr/local/etc/rsyncd.secrets backupuser@219.142.118.48::boke_2008_sum_olympic_video/
列出所有目录结构:
/usr/bin/rsync -vzrtopg --password-file=/usr/local/etc/rsyncd.secrets backupuser@219.142.118.48::boke_2008_sum_olympic_video/
匿名推送(不要用户名和密码):
/usr/bin/rsync -avgt /home/xiangdong2/rsync/* localhost::app4
app:
/usr/bin/rsync -vzrtopg --password-file=/home/xiangdong2/.rsync.secrets appspace@10.210.128.114::app_space_sina_com_cn
在home下建立test3目录(chmod -R a+x test3)然后同步(注意:/home/xiangdong2/.rsync.secrets文件的chmod 600 /home/xiangdong2/.rsync.secrets):
/usr/bin/rsync --password-file=/home/xiangdong2/.rsync.secrets test3 appspace@10.210.128.114::app_space_sina_com_cn -rt
客户端操作
客户端同步出错:
[test01@tonykorn02 ~]$ rsync -vzrtopg --progress test01@192.168.1.250::test01 /front/test01
Password:
@ERROR: auth failed on module test01
rsync error: error starting client-server protocol (code 5) at main.c(1296) [receiver=2.6.8]
[test01@tonykorn02 ~]$
原因:
secret file的文件属性有问题,该文件属性要是600的
"/home/FileServer:" 不明白这个目录是哪里来的 :)
rsync error: some files could not be transferred (code 23) at main.c(892) 有些文件不能被移动
是不是文件没有读的权限?
chmod -R a+r /home/wow/dl
★方式一:
一、服务器端(例:10.0.0.1*):
1、创建用户和组
groupadd www -g 48
useradd -u 48 -g www www
mkdir -p /opt/htdocs
chmod +w /opt/htdocs
chown www:www /opt/htdocs
2、编辑rsync的配置文件
vi /etc/rsyncd.conf
输入以下内容:
引用
uid=www
gid=www
max connections=10
use chroot=no
log file=/var/log/rsyncd.log
pid file=/var/run/rsyncd.pid
lock file=/var/run/rsyncd.lock
[zhangyan]
path=/opt/htdocs
comment = my htdocs
ignore errors
read only = no
hosts allow=10.0.0.21 10.0.0.22
3、启动rsync服务器端
/usr/bin/rsync --daemon
二、客户端(例:10.0.0.21和10.0.0.22):
1、创建一个shell脚本push.sh
vi push.sh
输入以下内容(10.0.0.1*为要推送到的目标服务器,zhangyan为服务器端rsyncd.conf配置文件中的模块名):
引用
#!/bin/sh
/usr/bin/rsync -vzrtopg --delete $1 10.0.0.10::zhangyan/
/usr/bin/rsync -vzrtopg --delete $1 10.0.0.11::zhangyan/
/usr/bin/rsync -vzrtopg --delete $1 10.0.0.16::zhangyan/
/usr/bin/rsync -vzrtopg --delete $1 10.0.0.19::zhangyan/
注:因为是内部局域网之间传输,这里没有设置密码。
2、赋予push.sh执行权限
chmod +x ./push.sh
3、同步推送客户端某个目录中(例:/home/zhanguan/abc)的文件到服务器端的/opt/htdocs目录:
./push.sh /home/zhanguan/abc/
注意:不要忘了abc后面的/。如果更改的文件太大,可以在上面语句的末尾加上空格和&号,推到后台执行。例:
./push.sh /home/zhanguan/abc/ &
★方式二:
一、服务器端(例:10.0.0.1*):
1、创建用户和组
groupadd www -g 48
useradd -u 48 -g www www
mkdir -p /opt/htdocs
chmod +w /opt/htdocs
chown www:www /opt/htdocs
passwd www
为www用户设置一个密码。
二、客户端:
1、同步推送客户端某个目录中(例:/home/zhanguan/abc)的文件到服务器端的/opt/htdocs目录:
/usr/bin/rsync -vzrtopg --delete /home/zhanguan/abc/ -e ssh www@10.0.0.10:/opt/htdocs/
输入密码,回车即可,无须服务器端启动rsync服务。
[ 2007-7-16 16:44 | by 张宴 ]
推送:
/usr/bin/rsync -avgt --progress --password-file=/usr/local/etc/rsyncd.secrets /data0/vshare/logs/user_search/iasks/* backupuser@219.142.118.48::boke_2008_sum_olympic_video
查看目录:
/usr/bin/rsync --password-file=/usr/local/etc/rsyncd.secrets backupuser@219.142.118.48::boke_2008_sum_olympic_video/
列出所有目录结构:
/usr/bin/rsync -vzrtopg --password-file=/usr/local/etc/rsyncd.secrets backupuser@219.142.118.48::boke_2008_sum_olympic_video/
匿名推送(不要用户名和密码):
/usr/bin/rsync -avgt /home/xiangdong2/rsync/* localhost::app4
app:
/usr/bin/rsync -vzrtopg --password-file=/home/xiangdong2/.rsync.secrets appspace@10.210.128.114::app_space_sina_com_cn
在home下建立test3目录(chmod -R a+x test3)然后同步(注意:/home/xiangdong2/.rsync.secrets文件的chmod 600 /home/xiangdong2/.rsync.secrets):
/usr/bin/rsync --password-file=/home/xiangdong2/.rsync.secrets test3 appspace@10.210.128.114::app_space_sina_com_cn -rt
客户端操作
客户端同步出错:
[test01@tonykorn02 ~]$ rsync -vzrtopg --progress test01@192.168.1.250::test01 /front/test01
Password:
@ERROR: auth failed on module test01
rsync error: error starting client-server protocol (code 5) at main.c(1296) [receiver=2.6.8]
[test01@tonykorn02 ~]$
原因:
secret file的文件属性有问题,该文件属性要是600的
"/home/FileServer:" 不明白这个目录是哪里来的 :)
rsync error: some files could not be transferred (code 23) at main.c(892) 有些文件不能被移动
是不是文件没有读的权限?
chmod -R a+r /home/wow/dl
作者: nickwolfe@CCF
CURL? 嗯,说来话长了~~~~
这东西现在已经是苹果机上内置的命令行工具之一了,可见其魅力之一斑
1)
二话不说,先从这里开始吧!
curl http://www.yahoo.com
回车之后,www.yahoo.com 的html就稀里哗啦地显示在屏幕上了~~~~~
2)
嗯,要想把读过来页面存下来,是不是要这样呢?
curl http://www.yahoo.com > page.html
当然可以,但不用这么麻烦的!
用curl的内置option就好,存下http的结果,用这个option: -o
curl -o page.html http://www.yahoo.com
这样,你就可以看到屏幕上出现一个下载页面进度指示。等进展到100%,自然就OK咯
3)
什么什么?!访问不到?肯定是你的proxy没有设定了。
使用curl的时候,用这个option可以指定http访问所使用的proxy服务器及其端口: -x
curl -x 123.45.67.89:1080 -o page.html http://www.yahoo.com
4)
访问有些网站的时候比较讨厌,他使用cookie来记录session信息。
像IE/NN这样的浏览器,当然可以轻易处理cookie信息,但我们的curl呢?.....
我们来学习这个option: -D <-- 这个是把http的response里面的cookie信息存到一个特别的文件中去
curl -x 123.45.67.89:1080 -o page.html -D cookie0001.txt http://www.yahoo.com
这样,当页面被存到page.html的同时,cookie信息也被存到了cookie0001.txt里面了
5)
那么,下一次访问的时候,如何继续使用上次留下的cookie信息呢?要知道,很多网站都是靠监视你的cookie信息,
来判断你是不是不按规矩访问他们的网站的。
这次我们使用这个option来把上次的cookie信息追加到http request里面去: -b
curl -x 123.45.67.89:1080 -o page1.html -D cookie0002.txt -b cookie0001.txt http://www.yahoo.com
这样,我们就可以几乎模拟所有的IE操作,去访问网页了!
6)
稍微等等~~~~~我好像忘记什么了~~~~~
对了!是浏览器信息~~~~
有些讨厌的网站总要我们使用某些特定的浏览器去访问他们,有时候更过分的是,还要使用某些特定的版本~~~~
NND,哪里有时间为了它去找这些怪异的浏览器呢!?
好在curl给我们提供了一个有用的option,可以让我们随意指定自己这次访问所宣称的自己的浏览器信息: -A
curl -A "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" -x 123.45.67.89:1080 -o page.html -D cookie0001.txt http://www.yahoo.com
这样,服务器端接到访问的要求,会认为你是一个运行在Windows 2000上的IE6.0,嘿嘿嘿,其实也许你用的是苹果机呢!
而"Mozilla/4.73 [en] (X11; U; Linux 2.2; 15 i686"则可以告诉对方你是一台PC上跑着的Linux,用的是Netscape 4.73,呵呵呵
7)
另外一个服务器端常用的限制方法,就是检查http访问的referer。比如你先访问首页,再访问里面所指定的下载页,这第二次访问的referer地址就是第一次访问成功后的页面地址。这样,服务器端只要发现对下载页面某次访问的referer地址不 是首页的地址,就可以断定那是个盗连了~~~~~
讨厌讨厌~~~我就是要盗连~~~~~!!
幸好curl给我们提供了设定referer的option: -e
curl -A "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" -x 123.45.67.89:1080 -e "mail.yahoo.com" -o page.html -D cookie0001.txt http://www.yahoo.com
这样,就可以骗对方的服务器,你是从mail.yahoo.com点击某个链接过来的了,呵呵呵
8)
写着写着发现漏掉什么重要的东西了!----- 利用curl 下载文件
刚才讲过了,下载页面到一个文件里,可以使用 -o ,下载文件也是一样。
比如,
curl -o 1.jpg http://cgi2.tky.3web.ne.jp/~zzh/screen1.JPG
这里教大家一个新的option: -O
大写的O,这么用:
curl -O http://cgi2.tky.3web.ne.jp/~zzh/screen1.JPG
这样,就可以按照服务器上的文件名,自动存在本地了!
再来一个更好用的。
如果screen1.JPG以外还有screen2.JPG、screen3.JPG、....、screen10.JPG需要下载,难不成还要让我们写一个script来完成这些操作?
不干!
在curl里面,这么写就可以了:
curl -O http://cgi2.tky.3web.ne.jp/~zzh/screen[1-10].JPG
呵呵呵,厉害吧?!~~~
9)
再来,我们继续讲解下载!
curl -O http://cgi2.tky.3web.ne.jp/~{zzh,nick}/[001-201].JPG
这样产生的下载,就是
~zzh/001.JPG
~zzh/002.JPG
...
~zzh/201.JPG
~nick/001.JPG
~nick/002.JPG
...
~nick/201.JPG
够方便的了吧?哈哈哈
咦?高兴得太早了。
由于zzh/nick下的文件名都是001,002...,201,下载下来的文件重名,后面的把前面的文件都给覆盖掉了~~~
没关系,我们还有更狠的!
curl -o #2_#1.jpg http://cgi2.tky.3web.ne.jp/~{zzh,nick}/[001-201].JPG
--这是.....自定义文件名的下载?
--对头,呵呵!
#1是变量,指的是{zzh,nick}这部分,第一次取值zzh,第二次取值nick
#2代表的变量,则是第二段可变部分---[001-201],取值从001逐一加到201
这样,自定义出来下载下来的文件名,就变成了这样:
原来: ~zzh/001.JPG ---> 下载后: 001-zzh.JPG
原来: ~nick/001.JPG ---> 下载后: 001-nick.JPG
这样一来,就不怕文件重名啦,呵呵
9)
继续讲下载
我们平时在windows平台上,flashget这样的工具可以帮我们分块并行下载,还可以断线续传。
curl在这些方面也不输给谁,嘿嘿
比如我们下载screen1.JPG中,突然掉线了,我们就可以这样开始续传
curl -c -O http://cgi2.tky.3wb.ne.jp/~zzh/screen1.JPG
当然,你不要拿个flashget下载了一半的文件来糊弄我~~~~别的下载软件的半截文件可不一定能用哦~~~
分块下载,我们使用这个option就可以了: -r
举例说明
比如我们有一个http://cgi2.tky.3web.ne.jp/~zzh/zhao1.mp3 要下载(赵老师的电话朗诵 :D )
我们就可以用这样的命令:
curl -r 0-10240 -o "zhao.part1" http:/cgi2.tky.3web.ne.jp/~zzh/zhao1.mp3 &
curl -r 10241-20480 -o "zhao.part1" http:/cgi2.tky.3web.ne.jp/~zzh/zhao1.mp3 &
curl -r 20481-40960 -o "zhao.part1" http:/cgi2.tky.3web.ne.jp/~zzh/zhao1.mp3 &
curl -r 40961- -o "zhao.part1" http:/cgi2.tky.3web.ne.jp/~zzh/zhao1.mp3
这样就可以分块下载啦。
不过你需要自己把这些破碎的文件合并起来
如果你用UNIX或苹果,用 cat zhao.part* > zhao.mp3就可以
如果用的是Windows,用copy /b 来解决吧,呵呵
上面讲的都是http协议的下载,其实ftp也一样可以用。
用法嘛,
curl -u name:passwd ftp://ip:port/path/file
或者大家熟悉的
curl ftp://name:passwd@ip:port/path/file
10)
说完了下载,接下来自然该讲上传咯
上传的option是 -T
比如我们向ftp传一个文件:
curl -T localfile -u name:passwd ftp://upload_site:port/path/
当然,向http服务器上传文件也可以
比如
curl -T localfile http://cgi2.tky.3web.ne.jp/~zzh/abc.cgi
注意,这时候,使用的协议是HTTP的PUT method
刚才说到PUT,嘿嘿,自然让老服想起来了其他几种methos还没讲呢!
GET和POST都不能忘哦。
http提交一个表单,比较常用的是POST模式和GET模式
GET模式什么option都不用,只需要把变量写在url里面就可以了
比如:
curl http://www.yahoo.com/login.cgi?user=nickwolfe&password=12345
而POST模式的option则是 -d
curl -d "user=nickwolfe&password=12345" http://www.yahoo.com/login.cgi
就相当于向这个站点发出一次登陆申请~~~~~
到底该用GET模式还是POST模式,要看对面服务器的程序设定。
一点需要注意的是,POST模式下的文件上的文件上传,比如
<form method="POST" enctype="multipar/form-data" action="http://cgi2.tky.3web.ne.jp/~zzh/up_file.cgi">
<input type=file name=upload>
<input type=submit name=nick value="go">
</form>
这样一个HTTP表单,我们要用curl进行模拟,就该是这样的语法:
curl -F upload=@localfile -F nick=go http://cgi2.tky.3web.ne.jp/~zzh/up_file.cgi
罗罗嗦嗦讲了这么多,其实curl还有很多很多技巧和用法
比如 https的时候使用本地证书,就可以这样
curl -E localcert.pem https://remote_server
再比如,你还可以用curl通过dict协议去查字典~~~~~
curl dict://dict.org/d:computer
今天就先讲到这里吧,呵呵。疯狂的curl功能,需要你---一起来发掘。
CURL? 嗯,说来话长了~~~~
这东西现在已经是苹果机上内置的命令行工具之一了,可见其魅力之一斑
1)
二话不说,先从这里开始吧!
curl http://www.yahoo.com
回车之后,www.yahoo.com 的html就稀里哗啦地显示在屏幕上了~~~~~
2)
嗯,要想把读过来页面存下来,是不是要这样呢?
curl http://www.yahoo.com > page.html
当然可以,但不用这么麻烦的!
用curl的内置option就好,存下http的结果,用这个option: -o
curl -o page.html http://www.yahoo.com
这样,你就可以看到屏幕上出现一个下载页面进度指示。等进展到100%,自然就OK咯
3)
什么什么?!访问不到?肯定是你的proxy没有设定了。
使用curl的时候,用这个option可以指定http访问所使用的proxy服务器及其端口: -x
curl -x 123.45.67.89:1080 -o page.html http://www.yahoo.com
4)
访问有些网站的时候比较讨厌,他使用cookie来记录session信息。
像IE/NN这样的浏览器,当然可以轻易处理cookie信息,但我们的curl呢?.....
我们来学习这个option: -D <-- 这个是把http的response里面的cookie信息存到一个特别的文件中去
curl -x 123.45.67.89:1080 -o page.html -D cookie0001.txt http://www.yahoo.com
这样,当页面被存到page.html的同时,cookie信息也被存到了cookie0001.txt里面了
5)
那么,下一次访问的时候,如何继续使用上次留下的cookie信息呢?要知道,很多网站都是靠监视你的cookie信息,
来判断你是不是不按规矩访问他们的网站的。
这次我们使用这个option来把上次的cookie信息追加到http request里面去: -b
curl -x 123.45.67.89:1080 -o page1.html -D cookie0002.txt -b cookie0001.txt http://www.yahoo.com
这样,我们就可以几乎模拟所有的IE操作,去访问网页了!
6)
稍微等等~~~~~我好像忘记什么了~~~~~
对了!是浏览器信息~~~~
有些讨厌的网站总要我们使用某些特定的浏览器去访问他们,有时候更过分的是,还要使用某些特定的版本~~~~
NND,哪里有时间为了它去找这些怪异的浏览器呢!?
好在curl给我们提供了一个有用的option,可以让我们随意指定自己这次访问所宣称的自己的浏览器信息: -A
curl -A "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" -x 123.45.67.89:1080 -o page.html -D cookie0001.txt http://www.yahoo.com
这样,服务器端接到访问的要求,会认为你是一个运行在Windows 2000上的IE6.0,嘿嘿嘿,其实也许你用的是苹果机呢!
而"Mozilla/4.73 [en] (X11; U; Linux 2.2; 15 i686"则可以告诉对方你是一台PC上跑着的Linux,用的是Netscape 4.73,呵呵呵
7)
另外一个服务器端常用的限制方法,就是检查http访问的referer。比如你先访问首页,再访问里面所指定的下载页,这第二次访问的referer地址就是第一次访问成功后的页面地址。这样,服务器端只要发现对下载页面某次访问的referer地址不 是首页的地址,就可以断定那是个盗连了~~~~~
讨厌讨厌~~~我就是要盗连~~~~~!!
幸好curl给我们提供了设定referer的option: -e
curl -A "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" -x 123.45.67.89:1080 -e "mail.yahoo.com" -o page.html -D cookie0001.txt http://www.yahoo.com
这样,就可以骗对方的服务器,你是从mail.yahoo.com点击某个链接过来的了,呵呵呵
8)
写着写着发现漏掉什么重要的东西了!----- 利用curl 下载文件
刚才讲过了,下载页面到一个文件里,可以使用 -o ,下载文件也是一样。
比如,
curl -o 1.jpg http://cgi2.tky.3web.ne.jp/~zzh/screen1.JPG
这里教大家一个新的option: -O
大写的O,这么用:
curl -O http://cgi2.tky.3web.ne.jp/~zzh/screen1.JPG
这样,就可以按照服务器上的文件名,自动存在本地了!
再来一个更好用的。
如果screen1.JPG以外还有screen2.JPG、screen3.JPG、....、screen10.JPG需要下载,难不成还要让我们写一个script来完成这些操作?
不干!
在curl里面,这么写就可以了:
curl -O http://cgi2.tky.3web.ne.jp/~zzh/screen[1-10].JPG
呵呵呵,厉害吧?!~~~
9)
再来,我们继续讲解下载!
curl -O http://cgi2.tky.3web.ne.jp/~{zzh,nick}/[001-201].JPG
这样产生的下载,就是
~zzh/001.JPG
~zzh/002.JPG
...
~zzh/201.JPG
~nick/001.JPG
~nick/002.JPG
...
~nick/201.JPG
够方便的了吧?哈哈哈
咦?高兴得太早了。
由于zzh/nick下的文件名都是001,002...,201,下载下来的文件重名,后面的把前面的文件都给覆盖掉了~~~
没关系,我们还有更狠的!
curl -o #2_#1.jpg http://cgi2.tky.3web.ne.jp/~{zzh,nick}/[001-201].JPG
--这是.....自定义文件名的下载?
--对头,呵呵!
#1是变量,指的是{zzh,nick}这部分,第一次取值zzh,第二次取值nick
#2代表的变量,则是第二段可变部分---[001-201],取值从001逐一加到201
这样,自定义出来下载下来的文件名,就变成了这样:
原来: ~zzh/001.JPG ---> 下载后: 001-zzh.JPG
原来: ~nick/001.JPG ---> 下载后: 001-nick.JPG
这样一来,就不怕文件重名啦,呵呵
9)
继续讲下载
我们平时在windows平台上,flashget这样的工具可以帮我们分块并行下载,还可以断线续传。
curl在这些方面也不输给谁,嘿嘿
比如我们下载screen1.JPG中,突然掉线了,我们就可以这样开始续传
curl -c -O http://cgi2.tky.3wb.ne.jp/~zzh/screen1.JPG
当然,你不要拿个flashget下载了一半的文件来糊弄我~~~~别的下载软件的半截文件可不一定能用哦~~~
分块下载,我们使用这个option就可以了: -r
举例说明
比如我们有一个http://cgi2.tky.3web.ne.jp/~zzh/zhao1.mp3 要下载(赵老师的电话朗诵 :D )
我们就可以用这样的命令:
curl -r 0-10240 -o "zhao.part1" http:/cgi2.tky.3web.ne.jp/~zzh/zhao1.mp3 &
curl -r 10241-20480 -o "zhao.part1" http:/cgi2.tky.3web.ne.jp/~zzh/zhao1.mp3 &
curl -r 20481-40960 -o "zhao.part1" http:/cgi2.tky.3web.ne.jp/~zzh/zhao1.mp3 &
curl -r 40961- -o "zhao.part1" http:/cgi2.tky.3web.ne.jp/~zzh/zhao1.mp3
这样就可以分块下载啦。
不过你需要自己把这些破碎的文件合并起来
如果你用UNIX或苹果,用 cat zhao.part* > zhao.mp3就可以
如果用的是Windows,用copy /b 来解决吧,呵呵
上面讲的都是http协议的下载,其实ftp也一样可以用。
用法嘛,
curl -u name:passwd ftp://ip:port/path/file
或者大家熟悉的
curl ftp://name:passwd@ip:port/path/file
10)
说完了下载,接下来自然该讲上传咯
上传的option是 -T
比如我们向ftp传一个文件:
curl -T localfile -u name:passwd ftp://upload_site:port/path/
当然,向http服务器上传文件也可以
比如
curl -T localfile http://cgi2.tky.3web.ne.jp/~zzh/abc.cgi
注意,这时候,使用的协议是HTTP的PUT method
刚才说到PUT,嘿嘿,自然让老服想起来了其他几种methos还没讲呢!
GET和POST都不能忘哦。
http提交一个表单,比较常用的是POST模式和GET模式
GET模式什么option都不用,只需要把变量写在url里面就可以了
比如:
curl http://www.yahoo.com/login.cgi?user=nickwolfe&password=12345
而POST模式的option则是 -d
curl -d "user=nickwolfe&password=12345" http://www.yahoo.com/login.cgi
就相当于向这个站点发出一次登陆申请~~~~~
到底该用GET模式还是POST模式,要看对面服务器的程序设定。
一点需要注意的是,POST模式下的文件上的文件上传,比如
<form method="POST" enctype="multipar/form-data" action="http://cgi2.tky.3web.ne.jp/~zzh/up_file.cgi">
<input type=file name=upload>
<input type=submit name=nick value="go">
</form>
这样一个HTTP表单,我们要用curl进行模拟,就该是这样的语法:
curl -F upload=@localfile -F nick=go http://cgi2.tky.3web.ne.jp/~zzh/up_file.cgi
罗罗嗦嗦讲了这么多,其实curl还有很多很多技巧和用法
比如 https的时候使用本地证书,就可以这样
curl -E localcert.pem https://remote_server
再比如,你还可以用curl通过dict协议去查字典~~~~~
curl dict://dict.org/d:computer
今天就先讲到这里吧,呵呵。疯狂的curl功能,需要你---一起来发掘。
不断的学习PHP也好几年了,看了太多的程序代码,也写了太多,更是想了太多
现在有点后悔浪费的时间
开始的时候,整天查手册,研究每一个函数的使用
然后去写自己想写的东西,遇到问题还是看手册,找各种类库资源,然后再写出自己的类库
一直到现在,自己的类库也不断的在升级和更新
以前刚学的时候,总把PHP看得很强大,看着别人的程序觉得很牛B,以为有什么牛B的手册里没有的东西以致于让自己不断的深入学习
其实是完全错误的,只要是PHP开发的,管它什么函数,什么类,什么框架
最终实现起来就是那些手册里最基本的PHP函数,只不过,人家玩的是编程思想,换个写法而已
所以,看别人的程序,只要看函数就行了,其他的没啥!除了PHP其他还有更多需要学习的东西
不管什么PHP程序,好像几年后不完全重写的很少,生命周期和学习开发成本太高了
所以个人站长做站,就不要去考虑什么可维护,什么可扩展,什么健壮,都是些不切实际的东西
只要跑起来快,实现了你想做的东西就行了,管它代码再难看,谁管它
只要流量大了,用户喜欢了,赚钱了,花点小钱,你爱咋整就咋整,而且还不用自己动手,这样的例子见得还少吗?
从实际我的应用中来看,给我赚钱最多的,是我用最少的时间,写得最垃圾的程序
花最多时间,写得最“牛B”的程序,反而是赚得最少的
完全是成反比的
技术仅仅是工具,不要被工具玩了
比程序开发重要的还有如下这些
1. 网站内容,结构,易用性,分析
2. 流量分析
3. SEO
4. 联盟
引用许三多的话:“做有意义的事!”
现在有点后悔浪费的时间
开始的时候,整天查手册,研究每一个函数的使用
然后去写自己想写的东西,遇到问题还是看手册,找各种类库资源,然后再写出自己的类库
一直到现在,自己的类库也不断的在升级和更新
以前刚学的时候,总把PHP看得很强大,看着别人的程序觉得很牛B,以为有什么牛B的手册里没有的东西以致于让自己不断的深入学习
其实是完全错误的,只要是PHP开发的,管它什么函数,什么类,什么框架
最终实现起来就是那些手册里最基本的PHP函数,只不过,人家玩的是编程思想,换个写法而已
所以,看别人的程序,只要看函数就行了,其他的没啥!除了PHP其他还有更多需要学习的东西
不管什么PHP程序,好像几年后不完全重写的很少,生命周期和学习开发成本太高了
所以个人站长做站,就不要去考虑什么可维护,什么可扩展,什么健壮,都是些不切实际的东西
只要跑起来快,实现了你想做的东西就行了,管它代码再难看,谁管它
只要流量大了,用户喜欢了,赚钱了,花点小钱,你爱咋整就咋整,而且还不用自己动手,这样的例子见得还少吗?
从实际我的应用中来看,给我赚钱最多的,是我用最少的时间,写得最垃圾的程序
花最多时间,写得最“牛B”的程序,反而是赚得最少的
完全是成反比的
技术仅仅是工具,不要被工具玩了
比程序开发重要的还有如下这些
1. 网站内容,结构,易用性,分析
2. 流量分析
3. SEO
4. 联盟
引用许三多的话:“做有意义的事!”
nohup sh -c "for ((i=0;i<${#a};i++));do echo ${a:$i:1};done"
nohup: 忽略输入并把输出追加到"nohup.out"
#tail -f nohup.out
nohup: 忽略输入并把输出追加到"nohup.out"
#tail -f nohup.out
Windows下星际译王(StarDict)的安装
最早知道 " 星际译王" 这个程序,还是王垠的那篇《完全用linux工作》中知道的,以前一直是在FreeBSD系统上使用,安装也非常方便,直接ports就行了 :)
她非常精巧,可扩展的字典库和附录,以及可选安装的真人发声(比金山词霸发音标准多了!),这里所指的安装,只不过是解压复制而已
而且还是开源的,支持Linux,FreeBSD,Solaris,Win32
真是个好东西,别再为 金山词霸 的序列号发愁了~~~
OK,我们现在开始
一、在http://stardict.sourceforge.net/index.php下载以下3个文件
1、gtk-runtime-2.4.13-rev-a.exe (GTK 程序库)
2、stardict-2.4.4.exe (星际译王 程序)
3、WyabdcRealPeopleTTS.tar.bz2 (发声档案)
二、在http://stardict.sourceforge.net/Dictionaries.php下载所需的词典文件
比如我下载了:
stardict-cdict-gb-2.4.2.tar.bz2
stardict-kdic-computer-gb-2.4.2.tar.bz2
stardict-kdic-ec-11w-2.4.2.tar.bz2
stardict-langdao-ce-gb-2.4.2.tar.bz2
stardict-langdao-ec-gb-2.4.2.tar.bz2
stardict-oxford-gb-2.4.2.tar.bz2
stardict-powerword2007_pwqec-2.4.2.tar.bz2
stardict-xdict-ce-gb-2.4.2.tar.bz2
stardict-xdict-ec-gb-2.4.2.tar.bz2
在http://stardict.sourceforge.net/TreeDictionaries.php 下载附录资料
stardict-treedict-infoBrowse-zh_CN-2.4.2.tar.bz2
安装过程:
首先安装GTK运行环境,即先安装 gtk-runtime-2.4.13-rev-a.exe
安装星际译王主程序
安装WyabdcRealPeopleTTS.tar.bz2 (发声档案)
解压缩文件(过程有点漫长,慢慢等 :) )后将其放入星际译王安装目录下,即 ..\StarDict 下
安装字典文件
将字典文件解压后放入安装目录下的dic目录内即可,即..\StarDict\dic 内
安装附录文件
将附录文件stardict-treedict-infoBrowse-zh_CN-2.4.2.tar.bz2解压缩后得到的3个文件
infoBrowse-zh_CN.dict.dz
infoBrowse-zh_CN.ifo
infoBrowse-zh_CN.tdx
放入安装目录下的treedict目录内即可,即 ..\StarDict\treedict 内
安装即完成,启动星际译王,敬请的使用吧~~ :)
最早知道 " 星际译王" 这个程序,还是王垠的那篇《完全用linux工作》中知道的,以前一直是在FreeBSD系统上使用,安装也非常方便,直接ports就行了 :)
她非常精巧,可扩展的字典库和附录,以及可选安装的真人发声(比金山词霸发音标准多了!),这里所指的安装,只不过是解压复制而已
而且还是开源的,支持Linux,FreeBSD,Solaris,Win32
真是个好东西,别再为 金山词霸 的序列号发愁了~~~
OK,我们现在开始
一、在http://stardict.sourceforge.net/index.php下载以下3个文件
1、gtk-runtime-2.4.13-rev-a.exe (GTK 程序库)
2、stardict-2.4.4.exe (星际译王 程序)
3、WyabdcRealPeopleTTS.tar.bz2 (发声档案)
二、在http://stardict.sourceforge.net/Dictionaries.php下载所需的词典文件
比如我下载了:
stardict-cdict-gb-2.4.2.tar.bz2
stardict-kdic-computer-gb-2.4.2.tar.bz2
stardict-kdic-ec-11w-2.4.2.tar.bz2
stardict-langdao-ce-gb-2.4.2.tar.bz2
stardict-langdao-ec-gb-2.4.2.tar.bz2
stardict-oxford-gb-2.4.2.tar.bz2
stardict-powerword2007_pwqec-2.4.2.tar.bz2
stardict-xdict-ce-gb-2.4.2.tar.bz2
stardict-xdict-ec-gb-2.4.2.tar.bz2
在http://stardict.sourceforge.net/TreeDictionaries.php 下载附录资料
stardict-treedict-infoBrowse-zh_CN-2.4.2.tar.bz2
安装过程:
首先安装GTK运行环境,即先安装 gtk-runtime-2.4.13-rev-a.exe
安装星际译王主程序
安装WyabdcRealPeopleTTS.tar.bz2 (发声档案)
解压缩文件(过程有点漫长,慢慢等 :) )后将其放入星际译王安装目录下,即 ..\StarDict 下
安装字典文件
将字典文件解压后放入安装目录下的dic目录内即可,即..\StarDict\dic 内
安装附录文件
将附录文件stardict-treedict-infoBrowse-zh_CN-2.4.2.tar.bz2解压缩后得到的3个文件
infoBrowse-zh_CN.dict.dz
infoBrowse-zh_CN.ifo
infoBrowse-zh_CN.tdx
放入安装目录下的treedict目录内即可,即 ..\StarDict\treedict 内
安装即完成,启动星际译王,敬请的使用吧~~ :)
一个用GTK与MySQL 数据库管理新闻的程序
1、 数据库为 gtk_php
create table code_news
(
id int(9) not null default 0 auto_increment,
title char(255) not null,
author char(30) not null,
author_contact char(75) not null,
news text,
PRIMARY KEY (id),
UNIQUE ID (id)
);
2 、GTK 程序部分,用于图形化管理新闻 - admin.php
CODE:
[Copy to clipboard]
#!/usr/local/bin/php -q
<?
if(strtoupper(substr(PHP_OS, 0, 3)) == 'WIN')
dl('php_gtk.dll');
else
dl('php_gtk.so');
function destroy()
{
Gtk::main_quit();
}
function handle_select($clist,$row,$column,$event)
{
global $ret, $entry, $SELECTED_ID;
$id = $clist->get_text($row,0);
$SELECTED_ID = $id;
}
function add_record()
{
global $entry, $SELECTED_ID, $fields, $API_URL, $USERNAME, $PASSWORD;
while(list($f,$l) = each($fields))
{
$$f = $entry[$f]->get_text();
}
$news = $entry['news']->get_chars(0,$entry['news']->get_length());
$file = $API_URL.'?a=add&p='.$PASSWORD.'&u='.$USERNAME.
'&news[title]='.urlencode($title).'&news[author]='.urlencode($author).
'&news[author_contact]='.urlencode($author_contact).
'&news[news]='.urlencode($news);
$fp = fopen($file,'r');
if($fp)
{
$contents = trim(fread($fp,4096));
if(!eregi("^0:[A-Z]*",$contents))
{
clear_entries();
update_clist();
}
else
{
echo "n$contentsn";
}
}
reset($fields);
}
function delete_record()
{
global $entry, $SELECTED_ID, $USERNAME, $PASSWORD, $API_URL;
$file = $API_URL.'?u='.$USERNAME.'&p='.$PASSWORD.'&a=del&id='.$SELECTED_ID;
$fp = fopen($file,'r');
if($fp)
{
$contents = trim(fread($fp,4096));
if(!eregi("^0:[A-Z]*",$contents))
{
update_clist();
}
else
{
echo "n$contentsn";
}
}
}
function update_record()
{
global $entry, $SELECTED_ID;
echo "n************************* NOT IMPLEMENTED *************************n";
echo "nUPDATE RECORD : $SELECTED_IDn";
echo "n************************* NOT IMPLEMENTED *************************n";
}
function update_clist()
{
global $clist, $API_URL, $PASSWORD, $USERNAME, $ret;
// Grab everything from our API
$fp = fopen($API_URL.'?a=get&p='.$PASSWORD.'&u='.$USERNAME,'r');
if($fp)
{
$contents = fread($fp,4096);
if(!ereg("^0:[A-Z]*",$contents))
{
$clist->clear();
$ret = unserialize(trim($contents));
$clist->freeze();
while(list($id,$info) = each($ret))
{
// $info = $ret[$i];
$row = array($info['id'],$info['author'],$info['title']);
$clist->append($row);
}
$clist->thaw();
}
else
{
echo "nERROR: ".$contents."n";
}
}
}
function clear_entries()
{
global $entry;
$entry['title']->set_text('');
$entry['author']->set_text('');
$entry['author_contact']->set_text('');
// echo $entry['news']->get_text();
// $foo = $entry['news']->get_chars(0,$entry['news']->get_length());
// echo "n".$foo."n";
$entry['news']->backward_delete($entry['news']->get_length());
}
function delete_event()
{
return false;
}
$window = &new GtkWindow();
$window->connect('destroy','destroy');
$window->set_border_width(10);
$box = &new GtkVBox();
$window->add($box);
$box->show();
$fields = array(
title => 'Title: ',
author => 'Author: ',
author_contact => 'Author Contact: ');
// Set up our regular text fields
while(list($f,$l) = each($fields))
{
$vbox = &new GtkVBox();
$box->pack_start($vbox,false,false);
$vbox->show();
$vbox->set_border_width(3);
$hbox = &new GtkHBox();
$vbox->pack_start($hbox,false,false);
$hbox->show();
$label = &new GtkLabel("$l");
$label->set_usize(150,10);
$hbox->pack_start($label,false);
$label->show();
$entry[$f] = &new GtkEntry();
$hbox->pack_start($entry[$f],false);
$entry[$f]->show();
}
$vbox = &new GtkVBox();
$box->pack_start($vbox,false,false);
$vbox->show();
$vbox->set_border_width(3);
$label = &new GtkLabel('News:');
$vbox->pack_start($label);
$label->show();
$entry['news'] = &new GtkText();
$entry['news']->set_editable(TRUE);
$vbox->pack_start($entry['news']);
$entry['news']->show();
$buttons = array(
Add => 'add_record',
Delete => 'delete_record',
Update => 'update_record',
Clear => 'clear_entries',
Refresh => 'update_clist',
Quit => 'destroy');
$hbox = &new GtkHBox();
$hbox->set_border_width(3);
$vbox->pack_start($hbox,false,false);
$hbox->show();
while(list($l,$f) = each($buttons))
{
$button = &new GtkButton($l);
$button->connect('clicked',$f);
$hbox->pack_start($button);
$button->show();
}
$scrolled_win = &new GtkScrolledWindow();
$scrolled_win->set_border_width(5);
$scrolled_win->set_policy(GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
$titles = array('ID','Author','Title');
$clist = &new GtkClist(sizeof($titles),$titles);
$scrolled_win->add($clist);
$clist->show();
$USERNAME = md5('joestump');
$PASSWORD = md5('phpgtk');
$API_URL = 'http://127.0.0.1/gtk/news_api/api.php';
// Grab everything from our API
update_clist();
$clist->set_usize(400,300);
$clist->connect('select-row','handle_select');
$auto_resize = array(0,1);
for($i = 0 ; $i < sizeof($auto_resize) ; ++$i)
$clist->set_column_auto_resize($auto_resize[$i],true);
$vbox->pack_start($scrolled_win);
$scrolled_win->show();
$window->show_all();
Gtk::main();
?>
3、 用于执行管理程序,向数据库加入数据的代码 api.php
<?
// Change username and password accordingly
$link = mysql_connect('192.168.192.47','root','')
or die('0:DB ERROR');
mysql_select_db('gtk_php',$link) or die('0:DB ERROR');
// Create a username and password to protect the
// API from outside people. THIS IS VERY IMPORTANT!
$USERNAME = md5('joestump');
$PASSWORD = md5('phpgtk');
switch($a)
{
case 'add':
// Make sure we are getting the 4 fields
// we want
if(sizeof($news) == 4)
{
// Check the given username and password against
// the ones we have - $p and $u are md5()'d in the
// GTK app and then sent along so no one can easily
// decrypt them.
if($p == $PASSWORD && $u == $USERNAME)
{
// extract($news);
while(list($key,$val) = each($news))
$$key = addslashes($val);
$sql = "INSERT INTO code_news
(title,author,author_contact,news)
VALUES
('$title','$author','$author_contact','$news')";
$r = mysql_query($sql);
if($r)
{
if(mysql_affected_rows($r))
echo '1:SUCCESS';
else
echo '0:FAILURE';
}
}
else
{
echo '0:BAD PASSWORD';
}
}
else
{
echo '0:BAD INFO ARRAY';
}
break;
case 'get':
if($p == $PASSWORD && $u == $USERNAME)
{
$sql = "SELECT * FROM code_news";
$r = mysql_query($sql);
if(@mysql_num_rows($r))
{
while($row = mysql_fetch_assoc($r))
$ret[$row['id']] = $row;
echo serialize($ret);
}
else
{
echo '0:NO RECORDS';
}
}
break;
case 'del':
if($id)
{
if($p == $PASSWORD && $u == $USERNAME)
{
$sql = "SELECT * FROM code_news WHERE id='$id'";
$r = mysql_query($sql);
if(@mysql_num_rows($r))
{
$sql = "DELETE FROM code_news WHERE id='$id'";
$r = mysql_query($sql);
include('http://'.$SERVER_NAME.$PHP_SELF.'?u='.$USERNAME.'&p='.$PASSWORD.'&a=get');
}
else
{
echo '0:ID NOT ON RECORD';
}
}
}
else
{
echo '0:NO ID GIVEN';
}
break;
default:
echo '0:UNRECOGNIZED ACCESS';
}
?>
4 、显示新闻 不用多说了- news.php
<?
// Change username and password accordingly
$link = mysql_connect('192.168.192.47','root','')
or die('0:DB ERROR');
mysql_select_db('gtk_php',$link) or die('0:DB ERROR');
$sql = "SELECT * FROM code_news";
$r = mysql_query($sql);
if(@mysql_num_rows($r))
{
while($row = mysql_fetch_array($r))
{
extract($row);
echo '<b>'.$title.'</b>
';
if(ereg("@",$author_contact))
$href = 'mailto:'.$author_contact;
else
$href = $author_contact;
echo 'Posted By: <a href="'.$href.'">'.$author.'</a>
';
echo $news.'<hr>';
}
}
else
{
echo 'NO NEWS!';
}
?>
1、 数据库为 gtk_php
create table code_news
(
id int(9) not null default 0 auto_increment,
title char(255) not null,
author char(30) not null,
author_contact char(75) not null,
news text,
PRIMARY KEY (id),
UNIQUE ID (id)
);
2 、GTK 程序部分,用于图形化管理新闻 - admin.php
CODE:
[Copy to clipboard]
#!/usr/local/bin/php -q
<?
if(strtoupper(substr(PHP_OS, 0, 3)) == 'WIN')
dl('php_gtk.dll');
else
dl('php_gtk.so');
function destroy()
{
Gtk::main_quit();
}
function handle_select($clist,$row,$column,$event)
{
global $ret, $entry, $SELECTED_ID;
$id = $clist->get_text($row,0);
$SELECTED_ID = $id;
}
function add_record()
{
global $entry, $SELECTED_ID, $fields, $API_URL, $USERNAME, $PASSWORD;
while(list($f,$l) = each($fields))
{
$$f = $entry[$f]->get_text();
}
$news = $entry['news']->get_chars(0,$entry['news']->get_length());
$file = $API_URL.'?a=add&p='.$PASSWORD.'&u='.$USERNAME.
'&news[title]='.urlencode($title).'&news[author]='.urlencode($author).
'&news[author_contact]='.urlencode($author_contact).
'&news[news]='.urlencode($news);
$fp = fopen($file,'r');
if($fp)
{
$contents = trim(fread($fp,4096));
if(!eregi("^0:[A-Z]*",$contents))
{
clear_entries();
update_clist();
}
else
{
echo "n$contentsn";
}
}
reset($fields);
}
function delete_record()
{
global $entry, $SELECTED_ID, $USERNAME, $PASSWORD, $API_URL;
$file = $API_URL.'?u='.$USERNAME.'&p='.$PASSWORD.'&a=del&id='.$SELECTED_ID;
$fp = fopen($file,'r');
if($fp)
{
$contents = trim(fread($fp,4096));
if(!eregi("^0:[A-Z]*",$contents))
{
update_clist();
}
else
{
echo "n$contentsn";
}
}
}
function update_record()
{
global $entry, $SELECTED_ID;
echo "n************************* NOT IMPLEMENTED *************************n";
echo "nUPDATE RECORD : $SELECTED_IDn";
echo "n************************* NOT IMPLEMENTED *************************n";
}
function update_clist()
{
global $clist, $API_URL, $PASSWORD, $USERNAME, $ret;
// Grab everything from our API
$fp = fopen($API_URL.'?a=get&p='.$PASSWORD.'&u='.$USERNAME,'r');
if($fp)
{
$contents = fread($fp,4096);
if(!ereg("^0:[A-Z]*",$contents))
{
$clist->clear();
$ret = unserialize(trim($contents));
$clist->freeze();
while(list($id,$info) = each($ret))
{
// $info = $ret[$i];
$row = array($info['id'],$info['author'],$info['title']);
$clist->append($row);
}
$clist->thaw();
}
else
{
echo "nERROR: ".$contents."n";
}
}
}
function clear_entries()
{
global $entry;
$entry['title']->set_text('');
$entry['author']->set_text('');
$entry['author_contact']->set_text('');
// echo $entry['news']->get_text();
// $foo = $entry['news']->get_chars(0,$entry['news']->get_length());
// echo "n".$foo."n";
$entry['news']->backward_delete($entry['news']->get_length());
}
function delete_event()
{
return false;
}
$window = &new GtkWindow();
$window->connect('destroy','destroy');
$window->set_border_width(10);
$box = &new GtkVBox();
$window->add($box);
$box->show();
$fields = array(
title => 'Title: ',
author => 'Author: ',
author_contact => 'Author Contact: ');
// Set up our regular text fields
while(list($f,$l) = each($fields))
{
$vbox = &new GtkVBox();
$box->pack_start($vbox,false,false);
$vbox->show();
$vbox->set_border_width(3);
$hbox = &new GtkHBox();
$vbox->pack_start($hbox,false,false);
$hbox->show();
$label = &new GtkLabel("$l");
$label->set_usize(150,10);
$hbox->pack_start($label,false);
$label->show();
$entry[$f] = &new GtkEntry();
$hbox->pack_start($entry[$f],false);
$entry[$f]->show();
}
$vbox = &new GtkVBox();
$box->pack_start($vbox,false,false);
$vbox->show();
$vbox->set_border_width(3);
$label = &new GtkLabel('News:');
$vbox->pack_start($label);
$label->show();
$entry['news'] = &new GtkText();
$entry['news']->set_editable(TRUE);
$vbox->pack_start($entry['news']);
$entry['news']->show();
$buttons = array(
Add => 'add_record',
Delete => 'delete_record',
Update => 'update_record',
Clear => 'clear_entries',
Refresh => 'update_clist',
Quit => 'destroy');
$hbox = &new GtkHBox();
$hbox->set_border_width(3);
$vbox->pack_start($hbox,false,false);
$hbox->show();
while(list($l,$f) = each($buttons))
{
$button = &new GtkButton($l);
$button->connect('clicked',$f);
$hbox->pack_start($button);
$button->show();
}
$scrolled_win = &new GtkScrolledWindow();
$scrolled_win->set_border_width(5);
$scrolled_win->set_policy(GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
$titles = array('ID','Author','Title');
$clist = &new GtkClist(sizeof($titles),$titles);
$scrolled_win->add($clist);
$clist->show();
$USERNAME = md5('joestump');
$PASSWORD = md5('phpgtk');
$API_URL = 'http://127.0.0.1/gtk/news_api/api.php';
// Grab everything from our API
update_clist();
$clist->set_usize(400,300);
$clist->connect('select-row','handle_select');
$auto_resize = array(0,1);
for($i = 0 ; $i < sizeof($auto_resize) ; ++$i)
$clist->set_column_auto_resize($auto_resize[$i],true);
$vbox->pack_start($scrolled_win);
$scrolled_win->show();
$window->show_all();
Gtk::main();
?>
3、 用于执行管理程序,向数据库加入数据的代码 api.php
<?
// Change username and password accordingly
$link = mysql_connect('192.168.192.47','root','')
or die('0:DB ERROR');
mysql_select_db('gtk_php',$link) or die('0:DB ERROR');
// Create a username and password to protect the
// API from outside people. THIS IS VERY IMPORTANT!
$USERNAME = md5('joestump');
$PASSWORD = md5('phpgtk');
switch($a)
{
case 'add':
// Make sure we are getting the 4 fields
// we want
if(sizeof($news) == 4)
{
// Check the given username and password against
// the ones we have - $p and $u are md5()'d in the
// GTK app and then sent along so no one can easily
// decrypt them.
if($p == $PASSWORD && $u == $USERNAME)
{
// extract($news);
while(list($key,$val) = each($news))
$$key = addslashes($val);
$sql = "INSERT INTO code_news
(title,author,author_contact,news)
VALUES
('$title','$author','$author_contact','$news')";
$r = mysql_query($sql);
if($r)
{
if(mysql_affected_rows($r))
echo '1:SUCCESS';
else
echo '0:FAILURE';
}
}
else
{
echo '0:BAD PASSWORD';
}
}
else
{
echo '0:BAD INFO ARRAY';
}
break;
case 'get':
if($p == $PASSWORD && $u == $USERNAME)
{
$sql = "SELECT * FROM code_news";
$r = mysql_query($sql);
if(@mysql_num_rows($r))
{
while($row = mysql_fetch_assoc($r))
$ret[$row['id']] = $row;
echo serialize($ret);
}
else
{
echo '0:NO RECORDS';
}
}
break;
case 'del':
if($id)
{
if($p == $PASSWORD && $u == $USERNAME)
{
$sql = "SELECT * FROM code_news WHERE id='$id'";
$r = mysql_query($sql);
if(@mysql_num_rows($r))
{
$sql = "DELETE FROM code_news WHERE id='$id'";
$r = mysql_query($sql);
include('http://'.$SERVER_NAME.$PHP_SELF.'?u='.$USERNAME.'&p='.$PASSWORD.'&a=get');
}
else
{
echo '0:ID NOT ON RECORD';
}
}
}
else
{
echo '0:NO ID GIVEN';
}
break;
default:
echo '0:UNRECOGNIZED ACCESS';
}
?>
4 、显示新闻 不用多说了- news.php
<?
// Change username and password accordingly
$link = mysql_connect('192.168.192.47','root','')
or die('0:DB ERROR');
mysql_select_db('gtk_php',$link) or die('0:DB ERROR');
$sql = "SELECT * FROM code_news";
$r = mysql_query($sql);
if(@mysql_num_rows($r))
{
while($row = mysql_fetch_array($r))
{
extract($row);
echo '<b>'.$title.'</b>
';
if(ereg("@",$author_contact))
$href = 'mailto:'.$author_contact;
else
$href = $author_contact;
echo 'Posted By: <a href="'.$href.'">'.$author.'</a>
';
echo $news.'<hr>';
}
}
else
{
echo 'NO NEWS!';
}
?>
<?
/*
A little sample script that takes SQL query from user, sends it to the MySQL server and
displays the result of query in new window.
DON'T FORGET TO CHANGE SERVER, USERNAME AND PASSWORD IN MYSQL_PCONNECT FUNCTION!!
I'll be glad for any comments.
Adam Rambousek - rambousek@volny.cz
*/
if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN')
dl('php_gtk.dll');
else
dl('php_gtk.so');
$windows = array();
function delete_event($window, $event)
{
$window->hide();
return true;
}
function close_window($widget)
{
$window = $widget->get_toplevel();
$window->hide();
}
/*
Called when clist column is clicked. It sets sorting by the clicked column.
*/
function clist_click_column($clist, $column) {
$clist->set_sort_column($column);
$clist->sort();
}
/*
Function displaying the result of query.
*/
function do_query($query)
{
global $windows;
//if the query_window is opened, let's close it
if (isset($windows['query_window'])) {
close_window($windows['query_window']);
}
$window = &new GtkWindow;
$windows['query_window'] = $window;
$window->set_name('query_window');
$window->connect('delete-event', 'delete_event');
$window->set_policy(false, true,false);
$window->set_title('Query result');
$window->set_uposition(220,85);
$box1 = &new GtkVBox();
$window->add($box1);
//frame displaying entered sql query
$frame = &new GtkFrame('MySQL Query');
$box1->pack_start($frame,false);
$label = &new GtkLabel($query->get_text());
$frame->add($label);
//frame displaying clist with the query result
$frame = &new GtkFrame('MySQL Query Result');
$box1->pack_start($frame,true);
//we'll display the result with scrollbars
$scrolled_win = &new GtkScrolledWindow();
$scrolled_win->set_border_width(5);
$scrolled_win->set_policy(GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
$frame->add($scrolled_win);
/*here we deal with the result
if mysql_query called with the query entered in main window, return a result
we can display clist
*/
if ($result = mysql_query($query->get_text())) {
/*
at first, keys array contains the names of columns
*/
if ($data = mysql_fetch_array($result)) {
$i=0;
$keys = array();
while (list($key,$val) = each($data)) {
if ($i%2) $keys[]=$key;
$i++;
}
}
/*
now we can prepare the clist, keys are the titles of columns and the number
of columns is equal to the number of keys
*/
$clist = &new GtkCList(count($keys), $keys);
$clist->connect('click_column', 'clist_click_column');
//we sets the auto_resize for each column
for ($i=0;$i<count($keys);$i++) $clist->set_column_auto_resize($i, true);
$scrolled_win->add($clist);
/*
now the data from result
we get the data from each row to row_data array and then we append this
array to the clist as a new row
*/
do {
for($i=0; $i < count($data)/2; $i++){
$row_data[$i] = $data[$i];
}
$clist->append($row_data);
} while ($data = mysql_fetch_array($result));
}
$button = &new GtkButton('close window');
$button->connect('clicked', 'close_window');
$box1->pack_start($button,false);
$button->set_flags(GTK_CAN_DEFAULT);
$button->grab_default();
$window->show_all();
}
function main_window()
{
$window = &new GtkWindow();
$window->set_policy(false,true,false);
$window->set_name('main_window');
$window->set_title('MySQL Query sample');
$window->set_uposition(80,80);
$window->connect_object('destroy', array('gtk', 'main_quit'));
$window->connect_object('delete-event', array('gtk', 'false'));
$box1 = &new GtkVBox();
$window->add($box1);
$frame = &new GtkFrame('MySQL Query');
$box1->pack_start($frame,false);
$entry = &new GtkEntry();
$frame->add($entry);
$separator = &new GtkHSeparator();
$box1->pack_start($separator,false);
$button = &new GtkButton('Do Query');
$button->connect_object('clicked', 'do_query',$entry);
$box1->add($button);
$separator = &new GtkHSeparator();
$box1->pack_start($separator,false);
$button = &new GtkButton('Quit');
$button->connect_object('clicked', array('gtk', 'main_quit'));
$box1->add($button);
$window->show_all();
}
mysql_pconnect("SERVER","USERNAME","PASSWORD") or die("can't connect to server");
main_window();
Gtk::main();
?>
/*
A little sample script that takes SQL query from user, sends it to the MySQL server and
displays the result of query in new window.
DON'T FORGET TO CHANGE SERVER, USERNAME AND PASSWORD IN MYSQL_PCONNECT FUNCTION!!
I'll be glad for any comments.
Adam Rambousek - rambousek@volny.cz
*/
if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN')
dl('php_gtk.dll');
else
dl('php_gtk.so');
$windows = array();
function delete_event($window, $event)
{
$window->hide();
return true;
}
function close_window($widget)
{
$window = $widget->get_toplevel();
$window->hide();
}
/*
Called when clist column is clicked. It sets sorting by the clicked column.
*/
function clist_click_column($clist, $column) {
$clist->set_sort_column($column);
$clist->sort();
}
/*
Function displaying the result of query.
*/
function do_query($query)
{
global $windows;
//if the query_window is opened, let's close it
if (isset($windows['query_window'])) {
close_window($windows['query_window']);
}
$window = &new GtkWindow;
$windows['query_window'] = $window;
$window->set_name('query_window');
$window->connect('delete-event', 'delete_event');
$window->set_policy(false, true,false);
$window->set_title('Query result');
$window->set_uposition(220,85);
$box1 = &new GtkVBox();
$window->add($box1);
//frame displaying entered sql query
$frame = &new GtkFrame('MySQL Query');
$box1->pack_start($frame,false);
$label = &new GtkLabel($query->get_text());
$frame->add($label);
//frame displaying clist with the query result
$frame = &new GtkFrame('MySQL Query Result');
$box1->pack_start($frame,true);
//we'll display the result with scrollbars
$scrolled_win = &new GtkScrolledWindow();
$scrolled_win->set_border_width(5);
$scrolled_win->set_policy(GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
$frame->add($scrolled_win);
/*here we deal with the result
if mysql_query called with the query entered in main window, return a result
we can display clist
*/
if ($result = mysql_query($query->get_text())) {
/*
at first, keys array contains the names of columns
*/
if ($data = mysql_fetch_array($result)) {
$i=0;
$keys = array();
while (list($key,$val) = each($data)) {
if ($i%2) $keys[]=$key;
$i++;
}
}
/*
now we can prepare the clist, keys are the titles of columns and the number
of columns is equal to the number of keys
*/
$clist = &new GtkCList(count($keys), $keys);
$clist->connect('click_column', 'clist_click_column');
//we sets the auto_resize for each column
for ($i=0;$i<count($keys);$i++) $clist->set_column_auto_resize($i, true);
$scrolled_win->add($clist);
/*
now the data from result
we get the data from each row to row_data array and then we append this
array to the clist as a new row
*/
do {
for($i=0; $i < count($data)/2; $i++){
$row_data[$i] = $data[$i];
}
$clist->append($row_data);
} while ($data = mysql_fetch_array($result));
}
$button = &new GtkButton('close window');
$button->connect('clicked', 'close_window');
$box1->pack_start($button,false);
$button->set_flags(GTK_CAN_DEFAULT);
$button->grab_default();
$window->show_all();
}
function main_window()
{
$window = &new GtkWindow();
$window->set_policy(false,true,false);
$window->set_name('main_window');
$window->set_title('MySQL Query sample');
$window->set_uposition(80,80);
$window->connect_object('destroy', array('gtk', 'main_quit'));
$window->connect_object('delete-event', array('gtk', 'false'));
$box1 = &new GtkVBox();
$window->add($box1);
$frame = &new GtkFrame('MySQL Query');
$box1->pack_start($frame,false);
$entry = &new GtkEntry();
$frame->add($entry);
$separator = &new GtkHSeparator();
$box1->pack_start($separator,false);
$button = &new GtkButton('Do Query');
$button->connect_object('clicked', 'do_query',$entry);
$box1->add($button);
$separator = &new GtkHSeparator();
$box1->pack_start($separator,false);
$button = &new GtkButton('Quit');
$button->connect_object('clicked', array('gtk', 'main_quit'));
$box1->add($button);
$window->show_all();
}
mysql_pconnect("SERVER","USERNAME","PASSWORD") or die("can't connect to server");
main_window();
Gtk::main();
?>
<?
if (!class_exists('gtk')) {
if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN')
dl('php_gtk.dll');
else
dl('php_gtk.so');
}
function destroy() {
Gtk::main_quit();
}
$window = &new GtkWindow();
$window->set_title("MySQL Manager");
$window->set_usize(300,300);
$window->connect('destroy', 'destroy');
$window->set_border_width(10);
$table=&new gtktable(5,3);
$window->add($table);
//add text boxes, button, and label
$usertext=&new gtklabel();
$usertext->set_text("Username:");
$table->attach($usertext,1,2,1,2);
$user=&new gtkentry();
$table->attach($user,2,3,1,2);
$passtext=&new gtklabel();
$passtext->set_text("Password:");
$table->attach($passtext,1,2,2,3);
$pass=&new gtkentry();
$table->attach($pass,2,3,2,3);
$sertext=&new gtklabel();
$sertext->set_text("Server:");
$table->attach($sertext,1,2,3,4);
$server=&new gtkentry();
$table->attach($server,2,3,3,4);
$conb=&new gtkbutton("Connect!");
$conb->connect('clicked','mconnect');
$table->attach($conb,1,3,4,5);
function put($what,$where) {
$where->set_text($what);
}
function mconnect() {
global $window,$pass,$user,$server;
$pass=$pass->get_text();
$user=$user->get_text();
$server=$server->get_text();
$conn=mysql_connect($server,$user,$pass);
mysql_select_db("simtown");
$q="select * from users";
while ($row=mysql_query($q)) {
print $row[0];
}
mysql_close($conn);
}
$window->show_all();
Gtk::main();
?>
if (!class_exists('gtk')) {
if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN')
dl('php_gtk.dll');
else
dl('php_gtk.so');
}
function destroy() {
Gtk::main_quit();
}
$window = &new GtkWindow();
$window->set_title("MySQL Manager");
$window->set_usize(300,300);
$window->connect('destroy', 'destroy');
$window->set_border_width(10);
$table=&new gtktable(5,3);
$window->add($table);
//add text boxes, button, and label
$usertext=&new gtklabel();
$usertext->set_text("Username:");
$table->attach($usertext,1,2,1,2);
$user=&new gtkentry();
$table->attach($user,2,3,1,2);
$passtext=&new gtklabel();
$passtext->set_text("Password:");
$table->attach($passtext,1,2,2,3);
$pass=&new gtkentry();
$table->attach($pass,2,3,2,3);
$sertext=&new gtklabel();
$sertext->set_text("Server:");
$table->attach($sertext,1,2,3,4);
$server=&new gtkentry();
$table->attach($server,2,3,3,4);
$conb=&new gtkbutton("Connect!");
$conb->connect('clicked','mconnect');
$table->attach($conb,1,3,4,5);
function put($what,$where) {
$where->set_text($what);
}
function mconnect() {
global $window,$pass,$user,$server;
$pass=$pass->get_text();
$user=$user->get_text();
$server=$server->get_text();
$conn=mysql_connect($server,$user,$pass);
mysql_select_db("simtown");
$q="select * from users";
while ($row=mysql_query($q)) {
print $row[0];
}
mysql_close($conn);
}
$window->show_all();
Gtk::main();
?>
三星研究院招C/C++ GTK软件工程师
发信站: BBS 水木清华站 (Tue Mar 11 10:30:27 2008), 站内
招聘职位 :C/C++软件工程师
招聘人数 : 7人
工作地点 :北京
职位描述 :Linux平台下的手机软件开发
职位要求 :
l 本科(2年以上工作经验)及硕士以上学历
l 精通C/C++语言编程,有扎实的编程功底和丰富的编程经验
l 掌握GTK+或QT开发,掌握GTK+者优先
l 熟悉嵌入式Linux,具有丰富开发经验
l 有输入法框架开发经验者优先
l 有模式识别、图象处理背景者优先
l 具有较强的团队精神,学习能力较强,能吃苦耐劳
l 较强的英语能力
应聘简历 投递地址:yan5.wang@samsung.com (请注明应聘职位)
简历接收 截止期限:2008年06月01日
发信站: BBS 水木清华站 (Tue Mar 11 10:30:27 2008), 站内
招聘职位 :C/C++软件工程师
招聘人数 : 7人
工作地点 :北京
职位描述 :Linux平台下的手机软件开发
职位要求 :
l 本科(2年以上工作经验)及硕士以上学历
l 精通C/C++语言编程,有扎实的编程功底和丰富的编程经验
l 掌握GTK+或QT开发,掌握GTK+者优先
l 熟悉嵌入式Linux,具有丰富开发经验
l 有输入法框架开发经验者优先
l 有模式识别、图象处理背景者优先
l 具有较强的团队精神,学习能力较强,能吃苦耐劳
l 较强的英语能力
应聘简历 投递地址:yan5.wang@samsung.com (请注明应聘职位)
简历接收 截止期限:2008年06月01日