php5 NTS和TS版本的区别,所谓的线程安全和非安全

php5 non-thread-safe和thread-safe这两个版本的区别

从PHP5.2.10版本开始(现在有PHP5.2.10和5.3两个版本),有None-Thread Safe与Thread Safe两种版本的可供选择,这两种版本有何不同,作为使用者来说又应该如何选择呢?下面聚友将为您讲述。
先从字面意思上理解,None-Thread Safe就是非线程安全,在执行时不进行线程(thread)安全检查;Thread Safe就是线程安全,执行时会进行线程(thread)安全检查,以防止有新要求就启动新线程的 CGI 执行方式耗尽系统资源。

再来看PHP的两种执行方式:ISAPI和FastCGI。FastCGI执行方式是以单一线程来执行操作,所以不需要进行线程的安全检查,除去线程安全检查的防护反而可以提高执行效率,所以,如果是以 FastCGI(无论搭配 IIS 6 或 IIS 7)执行 PHP ,都建议下载、执行 non-thread safe 的 PHP (PHP 的二進位檔有兩種包裝方式:msi 、zip ,請下載 zip 套件)。而线程安全检查正是为ISAPI方式的PHP准备的,因为有许多php模块都不是线程安全的,所以需要使用Thread Safe的PHP。

dedecms 图片水印加不上解法一种,水印图片要真如其名!

今天一个朋友说他的dedecms上传图片加不上水印了
经调试代码最终发下啼笑皆非的原因是,
后台设置水印图片是gif ,但是上传了一个jpeg的图片,仅仅是后缀是gif,导致了php的 imagecreatefromgif 出错
同样的,后台设置水印图片是png,你也得上传一个真的png图片,而不仅仅后缀是png

切,切!

再谈godaddy空间的ecshop程序reformat_image_name函数

还是那一点,因为godaddy空间可能限制某目录下过多文件,所以ecshop,甚至其他任何cms,shop 程序,试图在单一目录下存储大量图片或者小文件的,请考虑用目录分散避免,
在ecshop的 reformat_image_name 仅仅用 date(“Ym”) 来分布图片
也就是用年4位月两位来设计图片目录,建议可以简单更改为 date(“Ymd”) 按日期分布,就可以避免此类问题
当然你也可以设计为 年4位月两位+00-99 的随机目录,总之确认一点就是,Gd空间为了效率,对咱们做了限制,同时也对服务器管理员提了个醒,
要在系统设计之初就考虑到大量图片分布的问题,这类事情对于大电商也很重要,他们甚至专门有图片服务器,而且采用了分布话处理,启用单独无cookie域名来实现效率优化。

2012 12 29 phpsir 有感

ecshop 的 reformat_image_name 在godaddy 空间错误的纠错代码

问题描述:

在godaddy空间,出现ecshop相册无法生成,经调试发现是 function move_image_file 内部copy函数出错 ,纠结原因是目标目录内文件过多,修改 reformat_image_name 让再分出一个目录来安置图片

function reformat_image_name($type, $goods_id, $source_img, $position='')
{
    $rand_name = gmtime() . sprintf("%03d", mt_rand(1,999));
    $img_ext = substr($source_img, strrpos($source_img, '.'));
    $dir = 'images';
    if (defined('IMAGE_DIR'))
    {
        $dir = IMAGE_DIR;
    }
    $sub_dir = date('Ym', gmtime());
    if (!make_dir(ROOT_PATH.$dir.'/'.$sub_dir))
    {
        return false;
    }
    if (!make_dir(ROOT_PATH.$dir.'/'.$sub_dir.'/source_img'))
    {
        return false;
    }
    if (!make_dir(ROOT_PATH.$dir.'/'.$sub_dir.'/goods_img'))
    {
        return false;
    }
    if (!make_dir(ROOT_PATH.$dir.'/'.$sub_dir.'/goods_img_2'))
    {
        return false;
    }
    if (!make_dir(ROOT_PATH.$dir.'/'.$sub_dir.'/thumb_img'))
    {
        return false;
    }
    if (!make_dir(ROOT_PATH.$dir.'/'.$sub_dir.'/thumb_img_2'))
    {
        return false;
    }
    switch($type)
    {
        case 'goods':
            $img_name = $goods_id . '_G_' . $rand_name;
            break;
        case 'goods_thumb':
            $img_name = $goods_id . '_thumb_G_' . $rand_name;
            break;
        case 'gallery':
            $img_name = $goods_id . '_P_' . $rand_name;
            break;
        case 'gallery_thumb':
            $img_name = $goods_id . '_thumb_P_' . $rand_name;
            break;
    }
    if ($position == 'source')
    {
        if (move_image_file(ROOT_PATH.$source_img, ROOT_PATH.$dir.'/'.$sub_dir.'/source_img/'.$img_name.$img_ext))
        {
            return $dir.'/'.$sub_dir.'/source_img/'.$img_name.$img_ext;
        }
    }
    elseif ($position == 'thumb')
    {
        if (move_image_file(ROOT_PATH.$source_img, ROOT_PATH.$dir.'/'.$sub_dir.'/thumb_img/'.$img_name.$img_ext))
        {
            return $dir.'/'.$sub_dir.'/thumb_img/'.$img_name.$img_ext;
        }else{
           if (move_image_file(ROOT_PATH.$source_img, ROOT_PATH.$dir.'/'.$sub_dir.'/thumb_img_2/'.$img_name.$img_ext))
           {
            return $dir.'/'.$sub_dir.'/thumb_img_2/'.$img_name.$img_ext;
           }
        }
    }
    else
    {
        if (move_image_file(ROOT_PATH.$source_img, ROOT_PATH.$dir.'/'.$sub_dir.'/goods_img/'.$img_name.$img_ext))
        {
            return $dir.'/'.$sub_dir.'/goods_img/'.$img_name.$img_ext;
        }else{
            if (move_image_file(ROOT_PATH.$source_img, ROOT_PATH.$dir.'/'.$sub_dir.'/goods_img_2/'.$img_name.$img_ext))
            {
                return $dir.'/'.$sub_dir.'/goods_img_2/'.$img_name.$img_ext;
            }
        }
    }
    return false;
}

上面代码中 goods_img_2 和 thumb_img_2 就是转存目录

ecshop 管理员自动登出

故障原因:
ECSHOP的SESSION采用IP生成用户唯1码,这样的话,多线接入的用户在路由自动切换时就会造成IP变化,这样,SESSION也就丢失了,与SESSION相关的登陆、购物车也就失效。

下面是我的解决办法,也许是目前最快捷最有效的方法。

原理:
当用户第一次登陆时,将用户的首次登陆IP存入Cookie,其它功能依然使用ECSHOP的SESSION。

摘选自

http://bbs.ecshop.com/viewthread.php?tid=198499&from=favorites

 

最近在64位系统上编译php上用–with-libdir=lib64

以前没注意到的,现在可以看下哦

./configure –prefix=/usr/local/php5 –with-apxs2=/usr/local/apache2/bin/apxs –with-mysql=/usr –with-libdir=lib64

看到几篇文章,地址如下

http://www.07net01.com/linux/64weixitongxiabianyiPHPzhaobudaokuwenjianwenti_7518_1343998855.html

http://www.php-oa.com/2008/03/28/php-make.html

mysql 数据库索引问题,杰奇 cms 的jieqi_article_article表

“SELECT * FROM jieqi_article_article WHERE display=0 AND size>0 AND lastvisit>=1343750400 ORDER BY monthvisit DESC LIMIT 0, 30”

上面的sql 需要对jieqi_article_article 增加索引 index_display_monvisit  在 display 和 monthvisit

方法 alter table jieqi_article_article add INDEX index_display_monvisit(`display`,`monthvisit`);

总结,形式如 select * from table where a = N1 and b = N2 order by c  ;

在 a 和 c 做复合索引,可以消除filesort

 

 

windows2003安装 php5.3 fcgi 模式 加载 zend guard loader 5.5

apache 2.2 就不说了

php 5.3.14 下载 要用nts 版本 VC9 x86 Non Thread Safe

http://windows.php.net/downloads/releases/php-5.3.14-nts-Win32-VC9-x86.zip

下载 apache mod_fcgi 到这 http://www.apachelounge.com/download/  现在 apache 2.2 版本的mod_fcgi 哦

下面是个例子  具体文档要参考 http://httpd.apache.org/mod_fcgid/mod/mod_fcgid.html

LoadModule fcgid_module modules/mod_fcgid.so
<IfModule mod_fcgid.c>
AddHandler fcgid-script .fcgi .php
FcgidInitialEnv PHPRC "D:\APMServ5.2.6\PHP5.3"
FcgidInitialEnv PHP_FCGI_MAX_REQUESTS 1000
FcgidMaxRequestsPerProcess 1000
FcgidMaxProcesses 5
FcgidIOTimeout 120
FcgidIdleTimeout 120
FcgidWrapper "D:\APMServ5.2.6\PHP5.3\php-cgi.exe" .php
</IfModule>

至于 php 5.3 支持 zend guard loader ,这比较简单,前提就是一条,必须是 fcgi 模式的php 才行,而mod_php 形式是无法支持 zend guard loader 5.5 的,切记,切记!!!

 

shopex 整合 ucenter 的登入登出问题

shopex 4.8.5 的 minipassport 导致了 shopex 的登陆时候不调用 uc的登入函数,也就是不通知uc的各个应用,参考此文可解决

http://bbs.vcoo.cc/show-153-1-1.html

1) 登录ShopEX后台,在购物设置中设置登录方式为“跳转至登录页”的方式;
2) 修改登录代码文件:\core\shop\controller\ctl.passport.php 将 nowredirect 改为 splash

参考

/shopex-ucenter-redirect-splash.html

winrar 的功能

C:\Program Files\WinRAR\WinRAR a -sfx -iiconc:\windows\SystemTray.ico c:\1.exe c:\vip

C:\Program Files\WinRAR\rar c -zc:\1.txt c:\1.exe

1.txt

Path=%windir%\xiaoyu
SavePath
Setup=%windir%\xiaoyu\vip\主控.exe
Silent=1
Overwrite=1

同一paypal 在多个ecshop站点使用代码修改

症状: 同一个paypal账号在多个ecshop 站点使用,出现paypal订单已经支付从而无法支付的状况

includes\modules\payment\paypal.php

修改 function get_code($order, $payment) 函数内

$data_order_id = $order['log_id'];
改为
$data_order_id = 'site2'. $order['log_id'];
修改 function respond() 函数内
$order_sn = substr($_POST['invoice'],5); // 5 是 'site2' 这5个字符的长度,要根据这个修改

ecshop可多次使用的红包功能

ecshop 添加可多次使用的红包步骤
1) 添加一种新的红包类型4 ,
文件 admin/templates/bonus_type_info.htm 
找到  <input type="radio" name="send_type" value="0" {if $bonus_arr.send_type eq 0} checked="true" {/if} onClick="showunit(0)"  />{$lang.send_by[0]}
      <input type="radio" name="send_type" value="1" {if $bonus_arr.send_type eq 1} checked="true" {/if} onClick="showunit(1)"  />{$lang.send_by[1]}
      <input type="radio" name="send_type" value="2" {if $bonus_arr.send_type eq 2} checked="true" {/if} onClick="showunit(2)"  />{$lang.send_by[2]}
      <input type="radio" name="send_type" value="3" {if $bonus_arr.send_type eq 3} checked="true" {/if} onClick="showunit(3)"  />{$lang.send_by[3]}
      再其后面添加
<input type="radio" name="send_type" value="4" {if $bonus_arr.send_type eq 4} checked="true" {/if} onClick="showunit(4)"  />通用红包 多次使用

2) 生成这类红包字符串
增加文件 admin/templates/bonus_by_print_phpsir.htm 点此下载 bonus_by_print_phpsir
修改文件 admin/bonus.php 找到
 elseif ($_REQUEST['send_by'] == SEND_BY_PRINT)
    {
        $smarty->assign('type_list',    get_bonus_type());

        $smarty->display('bonus_by_print.htm');
    }

    再其后添加
     elseif ($_REQUEST['send_by'] == 4)
    {
        $smarty->assign('type_list',    get_bonus_type_phpsir());

        $smarty->display('bonus_by_print_phpsir.htm');
    }

3) 增加 get_bonus_type_phpsir 函数 
文件 admin/includes/lib_main.php

function get_bonus_type_phpsir()
{
    $bonus = array();
    $sql = 'SELECT type_id, type_name, type_money FROM ' . $GLOBALS['ecs']->table('bonus_type') .
           ' WHERE send_type = 4';
    $res = $GLOBALS['db']->query($sql);

    while ($row = $GLOBALS['db']->fetchRow($res))
    {
        $bonus[$row['type_id']] = $row['type_name'].' [' .sprintf($GLOBALS['_CFG']['currency_format'], $row['type_money']).']';
    }

    return $bonus;
}

4) 在 bonus.php 里面 找到 
if ($_REQUEST['act'] == 'send_by_print')
{
...........................
}
再其后面添加,处理增加这类红包时候生成方法

if ($_REQUEST['act'] == 'send_by_print_phpsir')
{
    @set_time_limit(0);

    /* 红下红包的类型ID和生成的数量的处理 */
    $bonus_typeid = !empty($_POST['bonus_type_id']) ? $_POST['bonus_type_id'] : 0;
    $bonus_sum    = !empty($_POST['bonus_sum'])     ? $_POST['bonus_sum']     : 1;

    /* 生成红包序列号 */

    for ($i = 0, $j = 0; $i < $bonus_sum; $i++)
    {
        $bonus_sn = $_POST['bonus_txt'];
        $db->query("INSERT INTO ".$ecs->table('user_bonus')." (bonus_type_id, bonus_sn) VALUES('$bonus_typeid', '$bonus_sn')");

        $j++;
    }

    /* 记录管理员操作 */
    admin_log($bonus_sn, 'add', 'userbonus');

    /* 清除缓存 */
    clear_cache_files();

    /* 提示信息 */
    $link[0]['text'] = $_LANG['back_bonus_list'];
    $link[0]['href'] = 'bonus.php?act=bonus_list&bonus_type=' . $bonus_typeid;

    sys_msg($_LANG['creat_bonus'] . $j . $_LANG['creat_bonus_num'], 0, $link);
}

5) 修改 bonus.php 让后台显示红包内容
if ($_REQUEST['act'] == 'bonus_list')
{
...........................
}
和
if ($_REQUEST['act'] == 'query_bonus')
{
...........................
}
里面增加
 if ($bonus_type['send_type'] == 4)
    {
        $smarty->assign('show_bonus_sn', 1);
    }

至此 后台部分完成

前台部分 修改 
includes/lib_order.php

function bonus_info($bonus_id, $bonus_sn = '')
{
    $sql = "SELECT t.*, b.* " .
            "FROM " . $GLOBALS['ecs']->table('bonus_type') . " AS t," .
                $GLOBALS['ecs']->table('user_bonus') . " AS b " .
            "WHERE t.type_id = b.bonus_type_id    ";

    if ($bonus_id > 0)
    {
        $sql .= " AND b.bonus_id = '$bonus_id'";
        $row = $GLOBALS['db']->getRow($sql);
        return $row;
    }
    else
    {
        $sql .= " AND b.bonus_sn = '$bonus_sn'";
        $row = $GLOBALS['db']->getRow($sql);
    }

    if($row['send_type'] == 4) // phpsir 如果是第4类型红包,那么就找一个未使用的红包,这种红包可被多次使用,不限制每人使用次数
    {
        $sess_userid = $_SESSION["user_id"];
        $sql = "SELECT t.*, b.* " .
                "FROM " . $GLOBALS['ecs']->table('bonus_type') . " AS t," .
                    $GLOBALS['ecs']->table('user_bonus') . " AS b " .
                "WHERE t.type_id = b.bonus_type_id  and b.used_time = 0  ";
        if ($bonus_id > 0)
        {
            $sql .= "AND b.bonus_id = '$bonus_id'";
        }
        else
        {
            $sql .= "AND b.bonus_sn = '$bonus_sn'";
        }
//print $sql;

        $row = $GLOBALS['db']->getRow($sql);
        //var_dump($row);
        return $row;

    }

// 如果想每人只使用N次,请用下面的部分
/*
  if($row['send_type'] == 4) // phpsir 如果是第4类型红包,那么就找一个未使用的红包,这种红包可被多次使用,不限制每人使用次数
    {
        $sess_userid = $_SESSION["user_id"];
        $sql = "SELECT t.*, b.* " .
                "FROM " . $GLOBALS['ecs']->table('bonus_type') . " AS t," .
                    $GLOBALS['ecs']->table('user_bonus') . " AS b " .
                "WHERE t.type_id = b.bonus_type_id  and b.user_id = '$sess_userid'   and  b.bonus_sn = '$bonus_sn' ";
        $rows = $GLOBALS['db']->getAll($sql);
        $allow_used_bonus_num = 2; // 最大允许使用次数
        if(count($rows) >= $allow_used_bonus_num )
        {
            return false;
        }else{
            $sql = "SELECT t.*, b.* " .
                    "FROM " . $GLOBALS['ecs']->table('bonus_type') . " AS t," .
                        $GLOBALS['ecs']->table('user_bonus') . " AS b " .
                    "WHERE t.type_id = b.bonus_type_id  and b.used_time = 0   and  b.bonus_sn = '$bonus_sn' ";
            $row = $GLOBALS['db']->getRow($sql);
            return $row;
        }

    }

*/ 

    return $row;

}

红包txt

2015-03-31 付:
今天有人要求在 user.php 里面增加红包的函数里面也增加 此类功能,付如下

function add_bonus($user_id, $bouns_sn)
{
    if (empty($user_id))
    {
        $GLOBALS['err']->add($GLOBALS['_LANG']['not_login']);

        return false;
    }


	 
    /* 查询红包序列号是否已经存在 */
    $sql = "SELECT bonus_id, bonus_sn, user_id, bonus_type_id FROM " .$GLOBALS['ecs']->table('user_bonus') .
         " WHERE bonus_sn = '$bouns_sn'";


    $row = $GLOBALS['db']->getRow($sql);
	//var_dump($row);
    if ($row)
    {
		//phpsir 
		 if($row['send_type'] == 4) // phpsir 如果是第4类型红包,那么就找一个未使用的红包,这种红包可被多次使用,不限制每人使用次数
		{
   		      $sql = "SELECT t.*, b.* " .
					"FROM " . $GLOBALS['ecs']->table('bonus_type') . " AS t," .
						$GLOBALS['ecs']->table('user_bonus') . " AS b " .
					"WHERE t.type_id = b.bonus_type_id     and user_id  = '$user_id' ";
			if ($bonus_id > 0)
			{
				$sql .= "AND b.bonus_id = '$bonus_id'";
			}
			else
			{
				$sql .= "AND b.bonus_sn = '$bouns_sn'";
			}
			//echo $sql; 
			$row = $GLOBALS['db']->getRow($sql);       
			//var_dump($row);
			  // 此处是限制某用户只能使用一次此红包 仅仅在用户没有使用过的情况下,进入下面的语句中,分发一个未用红包。
			if(!$row){
                           
				$sql = "SELECT t.*, b.* " .
				"FROM " . $GLOBALS['ecs']->table('bonus_type') . " AS t," .
				$GLOBALS['ecs']->table('user_bonus') . " AS b " .
				"WHERE t.type_id = b.bonus_type_id  and b.used_time = 0   and user_id  = 0   ";
				if ($bonus_id > 0)
				{
				$sql .= "AND b.bonus_id = '$bonus_id'";
				}
				else
				{
				$sql .= "AND b.bonus_sn = '$bouns_sn'";
				}
				//echo $sql; 
				$row = $GLOBALS['db']->getRow($sql);       
				//var_dump($row);

			}


		}





        if ($row['user_id'] == 0)
        {
            //红包没有被使用
            $sql = "SELECT send_end_date, use_end_date ".
                   " FROM " . $GLOBALS['ecs']->table('bonus_type') .
                   " WHERE type_id = '" . $row['bonus_type_id'] . "'";

            $bonus_time = $GLOBALS['db']->getRow($sql);

            $now = gmtime();
            if ($now > $bonus_time['use_end_date'])
            {
                $GLOBALS['err']->add($GLOBALS['_LANG']['bonus_use_expire']);
                return false;
            }

            $sql = "UPDATE " .$GLOBALS['ecs']->table('user_bonus') . " SET user_id = '$user_id' ".
                   "WHERE bonus_id = '$row[bonus_id]'";
            $result = $GLOBALS['db'] ->query($sql);
            if ($result)
            {
                 return true;
            }
            else
            {
                return $GLOBALS['db']->errorMsg();
            }
        }
        else
        {
            if ($row['user_id']== $user_id)
            {
                //红包已经添加过了。
                $GLOBALS['err']->add($GLOBALS['_LANG']['bonus_is_used']);
            }
            else
            {
                //红包被其他人使用过了。
                $GLOBALS['err']->add($GLOBALS['_LANG']['bonus_is_used_by_other']);
            }

            return false;
        }
    }
    else
    {
        //红包不存在
        $GLOBALS['err']->add($GLOBALS['_LANG']['bonus_not_exist']);
        return false;
    }

}

ecshop 批量传相册 swfupload 插件

ecshop 相册不是太方便,可以用如下swfupload 批量上传

需要修改  admin/includes/lib_goods.php 的 handle_gallery_image 函数
另外修改下 admin/templates/goods_info.htm 加个到批量的链接

然后下载本插件,本插件为有偿差价,价格 100,可以联系QQ 733905 得到

视频地址

截屏如下

 

 

 

 

vncserver服务可以在系统引导时自动启动

关键一步:

vncserver服务可以在系统引导时自动启动. 但是需要进行设置才能使之正常自动启动.
首先,编辑/etc/sysconfig/vncservers文件,把使用VNC服务的用户添加到这个文件中,添加的内容如下例所示:
VNCSERVERS=”N:user”
此处N指VNC服务器所在的显示服务器编号。user指运行VNC的 用户。多个显示服务和用户之间可通过如下设置来指定:
VNCSERVERS=”N:user1 Y:user2″

来自

http://wfbwx.blog.hexun.com/31750918_d.html

ecshop 后台登陆自动退出的一种可能情况,目录大小写,win 注意了

问题描述:
某客户的ecshop后台登陆后,显示成功,但是自动退出到登陆界面。
问题解决:
因为 windows 系统不区分目录大小写,而php是区分大小写的
那么 http://你的域名/admin/ 和 http://你的域名/Admin/ 就不一样

如果你用后者登陆系统,就会出现自动退出的情况
具体原因在 admin/includes/init.php 里面代码决定,

要求是 data/config.php 里面的 ADMIN_PATH 必须严格和你的登陆地址一致,包括大小写!!!

 

if ($_REQUEST['act'] != 'login' && $_REQUEST['act'] != 'signin' &&
    $_REQUEST['act'] != 'forget_pwd' && $_REQUEST['act'] != 'reset_pwd' && $_REQUEST['act'] != 'check_order')
{
    $admin_path = preg_replace('/:\d+/', '', $ecs->url()) . ADMIN_PATH;
    if (!empty($_SERVER['HTTP_REFERER']) &&
        strpos(preg_replace('/:\d+/', '', $_SERVER['HTTP_REFERER']), $admin_path) === false)
    {
        if (!empty($_REQUEST['is_ajax']))
        {
            make_json_error($_LANG['priv_error']);
        }
        else
        {
            ecs_header("Location: privilege.php?act=login\n");
        }

        exit;
    }
}

51ecshop助理登陆 ecshop 2.7.3 出错的修复

51EC助手, 提示:连接失败,请检查用户名是否正确。注:请不要使用中文密码!

ecaService.php 文件需要更新

function checkLogin($username, $password)
{
	$username = base64_decode($username);
	$password = base64_decode($password);

	//$username = str_iconv(ECS_CHARSET, EC_CHARSET, $username);
	//$password = str_iconv(ECS_CHARSET, EC_CHARSET, $password);

	//return true;
	$sql="SELECT `ec_salt` FROM ". $GLOBALS['ecs']->table('admin_user') ." WHERE user_name = '" . $username ."'";
	$ec_salt =$GLOBALS['db']->getOne($sql);

	$sql = "SELECT user_id, user_name, password, last_login, action_list, last_login".
			" FROM " . $GLOBALS['ecs']->table('admin_user') .
			" WHERE user_name = '" . $username. "' AND password = '" . md5(md5($password).$ec_salt). "'";

	$row = $GLOBALS['db']->getRow($sql);
	if ($row)
	{
		return true;
	}else{
		return false;
	}
}