WHMCS 7.x 开发小经验小结-修改首页、修改菜单、简化注册

WHMCS是个很出名的IDC供应商管理系统,但是由于是加密程序,很多东西改起来不容易。比如你想做个注册页面,你就没法子做,因为你不知道密码的加密方式。不过有一些东西还是可以自定义的。

自定义首页

由于是加密程序,所以index.php你无法修改,怎么办呢?下面提供几个方案解决这个问题。

子站处理

要么把whmcs放一个子域名,比如user.xx.com

要么把whmcs放一个子目录,或者www.xx.com/user/

但是这两种建议是安装之前想好,否则的话,就要去更新授权了。要去购买的地方提交更改。

默认首页处理

静态首页:直接放index.html,一般这个会是默认首页。

动态首页:修改nginx或者apache服务器的配置文件,让默认首页改为home.php

  1. # nginx 例子
  2. server_name sdtclass.com blog.xukhost.com;
  3. index home.php index.html index.htm index.php default.html default.htm default.php;

如果是虚拟主机,并且是apache服务器的,也可以用.htaccess定义默认首页。

  1. # .htaccess例子
  2. Directory Index home.php index.html index.php

重写index.php

有的人不喜欢重写定义首页,比如我。因为潜意识里index才是首页呢。而且WHMCS里,首页也是指向index.php,所以我提供了另一个思路。

保存index.php,然后新建一个index.php,这样可以自定义首页的内容了。但是,,,WHMCS比较新的版本里,很多地址打开都依赖index.php。所以我们需要做一个处理。

比如公告页面的菜单连接是:index.php?rp=/announcements

但是,其实 http://blog.xukhost.com/announcements.php 就可以打开(不用复制了,这是举例)。代码又是加密的,我们又无法修改菜单里的连接,怎么办呢?所以我们只好写个PHP来处理了。

  1. <?php
  2. //判断是否有参数
  3. if($_GET) {
  4.     //rp参数
  5.     $url = $_GET[‘rp’];
  6.     //判断是否是rp这个参数
  7.     if($url) {
  8.         //重定向
  9.         Header(“Location: $url.php”);
  10.         exit// 退出
  11.     }
  12. }
  13. ?>
  14. //如果上面不成立,会输出下面内容。下面是首页内容

测试了可行是可行,发现下载页的不一样,不是download.php,而是downloads.php。于是。。

  1. <?php
  2. if($_GET) {
  3.     $url = $_GET[‘rp’];
  4.     if($url) {
  5.         //判断是否是下载页,如果是则定义链接。
  6.         if($url == ‘/download’) {
  7.             Header(“Location: downloads.php”);
  8.             exit;
  9.         }
  10.         Header(“Location: $url.php”);
  11.         exit// 退出
  12.     }
  13. }
  14. ?>
  15. // 首页内容

然后好像就完美了?后来发现,不行啊,有的带id参数啊。于是乎用了stripos函数,这个函数是用于判断字符串里是否有这个字符。

  1. stripos(string,find,start)

可以参考:http://www.php.net/manual/zh/function.stripos.php

或者参考:http://www.w3school.com.cn/php/func_string_stripos.asp

实际应用如下:

  1. <?php
  2. if($_GET) {
  3.     $url = $_GET[‘rp’];
  4.     if($url) {
  5.         if($url == ‘/download’) {
  6.             Header(“Location: downloads.php”);
  7.             exit;
  8.         }elseifstripos($url, ‘/announcements/’) !== false){
  9.             //判断如果URL含有这部分字符,也就是新闻页的字符
  10.             $pid = mb_substr($url,15 ); //提取第15个和后面的,也就是id
  11.             Header(“Location: announcements.php?id=$pid”);
  12.             //重定向到重新拼接的URL
  13.             exit;
  14.         }
  15.         Header(“Location: $url.php”);
  16.         exit// 退出
  17.     }
  18. }
  19. ?>
  20. // 首页内容

你以为事情真的那么简单吗,我也想啊。。然后我发现帮助中心的URL就比较特殊了。。

比如:http://www.xukhost.com/index.php?rp=/knowledgebase/15/755.html

好吧,这个,,只能正则了。。于是。。

  1. <?php
  2. if($_GET) {
  3.     $url = $_GET[‘rp’];
  4.     if($url) {
  5.         if($url == ‘/download’) {
  6.             Header(“Location: downloads.php”);
  7.             exit;
  8.         }elseifstripos($url, ‘/announcements/’) !== false){
  9.             $pid = mb_substr($url,15 );
  10.             Header(“Location: announcements.php?id=$pid”);
  11.             exit;
  12.         }elseif(preg_match(‘#/knowledgebase/(\d+)#i’, $url$match)) {
  13.           $pid = $match[1];
  14.             Header(“Location: knowledgebase.php?action=displayarticle&id=$pid”);
  15.             exit;
  16.         }
  17.         Header(“Location: $url.php”);
  18.         exit// 退出
  19.     }
  20. }
  21. ?>
  22. // 首页内容

定义引用

经过这样的反复,反复,再反复,我都怀疑人生了。。。我觉得不行吧,既然能让index.php处理,何不直接让他处理呢?

所以也可以是,,,index.php改名,新的index判断是否有参数,如果是就引用这个,不是则输出首页内容。。

好吧,你以为我耍你们呢,其实这两个方案都是可以的。上面那个21行的代码暂时测试没问题。两个方案二选一啦。

自定义菜单

看了很久的模板代码,发现个问题,WHMCS新版本的菜单都是系统生成的了。。。但是,游客访问的话,菜单第一个是指向index.php,而登陆后的话,则是指向会员中心页,你说我这个地方翻译成什么都尴尬好吧?

后面我发现了,其实写死就好了。。。自己利用模板提供的判断方法,判断和引用即可。。

  1. {if $loggedin}
  2.     <ul class=“nav nav-menu”>
  3.         {include file=“$template/includes/menu.tpl” navbar=$primaryNavbar}
  4.     </ul>
  5. {else}
  6.     <ul class=“nav nav-menu”>
  7.         {include file=“$template/includes/menus.tpl”}
  8.     </ul>
  9. {/if}

上面menu.tpl是自带的,我写了个新的menus.tpl,然后这个新的就可以自己写菜单了。。。当然了,登陆页的菜单,也可以引用另一个文件来解决。这样两个菜单就都可以自定义了。不带navber参数即可。

简化注册

这个利用两个东西,一个是隐藏,一个是赋值。

比如,公司,地址2,这两个输入框不是必填,直接隐藏。

  1. <div class=“form-group” style=“display: none;”>
  2.     <label class=“col-sm-3 control-label” for=“companyname”>{$LANG.clientareacompanyname}</label>
  3.     <div class=“col-sm-6”>
  4.         <input type=“text” name=“companyname” id=“companyname” value=“{$clientcompanyname}” class=“form-control”/>
  5.     </div>
  6. </div>

上面用CSS(display:none;),隐藏了整个输入框。可是呢必填项不仅仅要隐藏,而且要加默认值,这样就可以避免不填写带来的无法跳过验证了。(不加密多好,可以直接去掉判断字符串长度。。。)

  1. <div class=“col-sm-6”>
  2.     <input type=“text” name=“city” id=“city” value=“city” class=“form-control” {if !in_array(‘city’, $optionalFields)}required{/if} />
  3. </div>

这个value里的变量,改为写死的city,这时候就可以了。变量囊是你填写后注册不了的时候返回才输出的。所以改为写死的,然后加css隐藏即可。【不过我不建议隐藏,因为域名注册需要。】

官方文档和API

当然了,WHMCS官方也有提供API,可以修改的东西还是有不少的。也可以做插件的。

官方文档:https://docs.whmcs.com/Main_Page

API文档:https://developers.whmcs.com/api/

PHP技巧-支付宝公钥自动整理工具开发思路和完整代码

写了上一篇文章之后,心血来潮想写个页面,做个便民工具什么的。就算声明不会存储他人密钥,可是万一别人还是不放心呢?赖上我怎么办?授人以鱼不如授人以渔嘛,本站的核心就是这个啊。所以~~~

截取函数

首先,要把这个东西整理出来,我们要让这个支付宝公钥变成四个部分,也就是三行64,一行24。第一个想到的方法是跑循环,可是我觉得没必要吧,一来我没想到什么函数适合,二来我其实心底里有个很熟悉的函数,那就是“mb_substr”这个啦。以前改过不少模板的时候,经常会用这个函数的。

官方文档:http://php.net/manual/zh/function.mb-substr.php

先来介绍下,mb_substr这个函数有四个参数:

参数 作用
str 必填,要截取的字符串变量
start 必填,开始的位置,指针第一个是0
length 可选,截取的数量,从开始位置计算,如果没这个参数则取到结尾
encoding 可选,编码格式,如果没指定则使用内部字符编码

用法示例

首先把密钥赋值给一个变量,然后用这个函数来截取字符串,再赋值变量,然后输出。

代码如下:

  1. //把密钥赋值给 $key 
  2. $key = ‘MIGfMA0G*******DAQAB’;
  3. //用mb_substr处理
  4. //把$key从第一个开始,也就是指针0,截取64个,编码UTF8
  5. $key1 = mb_substr( $key, 0, 64, ‘utf-8’);
  6. //输出变量的值
  7. echo $key1;

注意一点是,指针从0开始,所以0就是第一个,那么,64就是第65个。所以第二行的话应该这么写:

  1. //错误写法
  2. $key2 = mb_substr( $key, 65, 64, ‘utf-8’);
  3. //正确写法
  4. $key2 = mb_substr( $key, 64, 64, ‘utf-8’);

由于密钥都是字母数字和特定符号,不会出现中文或特殊符号,所以其实编码是可以不声明的,不过为了以防万一可以全局声明下,这样就不用写太多无用的定义了。代码有时候需要简洁点好。最后一个只剩下24,所以也可以不用声明了。

  1. //声明编码
  2. header(“Content-type: text/html; charset=utf-8”);
  3. //截取最后一段
  4. $key4 = mb_substr($key, 192);
  5. //或者
  6. $key4 = mb_substr($key, 192, 24);

完整代码

下面是完整代码,复制代码到记事本,替换$key里面的值,改为你的密钥,然后重命名为key.php。把文件放在PHP主机环境下运行打开即可得到转换后的内容,然后直接复制内容做成支付宝公钥。

  1. <?php
  2. header(“Content-type: text/html; charset=utf-8”);
  3. //替换括号里的内容。
  4. $key = ‘MIGfMA0G*******DAQAB’;
  5. $key1 = mb_substr($key, 0, 64);
  6. $key2 = mb_substr($key, 64, 64);
  7. $key3 = mb_substr($key, 128, 64);
  8. $key4 = mb_substr($key, 192);
  9. echo “—–BEGIN PUBLIC KEY—–<br>”;
  10. echo $key1.“<br>”;
  11. echo $key2.“<br>”;
  12. echo $key3.“<br>”;
  13. echo $key4.“<br>”;
  14. echo “—–END PUBLIC KEY—–<br>”;
  15. ?>

扩展阅读

1,由于证书格式规定,所以加了第12行和17行;

2,PHP中,多个变量或字符串之间,用“.”连接起来;

3:如果第三个参数没设定,第四个请勿设定,否则报错;

4:这个函数如果未开启,请在php.ini里修改开启。

开启方法,搜索“php_mbstring”,把;extension前面的分号去掉。然后重启环境。

5:如果想验证长度,可以利用另一个函数“strlen”。

  1. echo strlen(trim($key1)).’–‘;
  2. echo strlen(trim($key2)).’–‘;
  3. echo strlen(trim($key3)).’–‘;
  4. echo strlen(trim($key4));

实际如出如图

PHP DEBUG技巧-Division by zero报错处理

这几天有个opencart客户买了个模板,由于是新手要我帮忙装和调试,一开始说有个什么错误,可是我去看没发现。我是中文看的,英文下才有报错。

由于是付费买正版,发现问题也着急,应该是找作者解决的,找半天没找到作者联系方式。由于也是老客户了,反正也不会是大问题,还是我自己看看吧。下面进入正题,不BB了。

错误提示

在打开某些产品分类或者某些产品页面的时候,特定语言才报错。

错误是:Division by zero in 巴拉巴拉

错误原因

这个错误的原因,就是运算的过程中,被除数是0。上过小学的都知道“0是不可以作为被除数的”。

解决思路

1:判断值为0的时候跳过运算;

2:如果非要赋值给一个变量,可以做判断后赋固定值或者输出false,后面代码判断如果变量是true才使用它进行下一步代码的实现。

DEBUGING

解决问题之前,先来个两个小知识点:

1、在opencart中,vqmod的优先等级是最高的

2、哪里报错不一定错误就在哪里,但是首先看的还是报错的地方。

从上图中,我们找到了vqcache下对应的文件对应行数,发现如下代码:

  1. // Cosyone custom code starts   
  2. if ((float)$result[‘special’]) {
  3.     $sales_percantage = ((($this->tax->calculate($result[‘price’], $result[‘tax_class_id’], $this->config->get(‘config_tax’)))-($this->tax->calculate($result[‘special’], $result[‘tax_class_id’], $this->config->get(‘config_tax’))))/(($this->tax->calculate($result[‘price’], $result[‘tax_class_id’], $this->config->get(‘config_tax’)))/100));
  4. else {
  5.     $sales_percantage = false;
  6. }

从这个代码可以看出有若干个参数,我们留意“/”后面的被除数就好,这里被除数有两个地方,其中第二个是正整数100,可以排除。那么问题就在下面这段代码中:

  1. $this->tax->calculate($result[‘price’], $result[‘tax_class_id’], $this->config->get(‘config_tax’))

我们从上面这个方法里看到三个参数,分别用print_r打印了下参数的值,结果发现第二个参数“$result[‘tax_class_id’]”是“000000”。很显然,如果这个是0,我们就要让:

$sales_percantage  = false ;

所以我们这里的代码要修改为:

  1. // Cosyone custom code starts   
  2. if ((float)$result[‘special’] && $result[‘tax_class_id’]) {
  3.     $sales_percantage = ((($this->tax->calculate($result[‘price’], $result[‘tax_class_id’], $this->config->get(‘config_tax’)))-($this->tax->calculate($result[‘special’], $result[‘tax_class_id’], $this->config->get(‘config_tax’))))/(($this->tax->calculate($result[‘price’], $result[‘tax_class_id’], $this->config->get(‘config_tax’)))/100));
  4. else {
  5.     $sales_percantage = false;
  6. }

也就是,加多一个判断依据,必须满足两个值都存在的前提下,才进行如下运算,否则是false。

修改代码,保存代码,上传文件,刷新页面,警告提示语消失,over。

但是,毕竟我们改的是缓存文件,真正要修改好代码,我们还是要把代码写到核心文件或者插件的文件里。

修改源

首先,我们从三个地方查找,分别是:

核心文件:/catalog/controller/product/category.php;

vqmod:/vqmod/xml/*.xml;

ocmod:上传插件的ocmod.xml文件备份,或者数据库查看:oc_modification表xml字段;

虽然vqmod的优先等级高于ocmod,但是其实先从比较方便的地方找起也是可以的。有个方法可以排除是否ocmod。如果是ocmod插件的,缓存文件名必定有“system_storage_modification”。

但是也由于vqmod优先等级最高,所以被ocmod缓存的文件的文件名也可能有这个字样,所以排查的顺序如上所述。【如果报错指向“/system/storage/modification/”则一定是ocmod插件引起】

核心文件的话,编辑器打开ctrl+F进行关键字查找修改。

如果是vqmod的xml,要么排除法排除不可能是的文件,然后从可能是的文件里查找。如果文件太多就用notepad++等编辑器或者IDE工具,可以进行目录搜索,从中找到文件。

如果是ocmod,则用MYSQL工具进行字段like %…% 搜索,或者用SQL语句:

  1. SELECT * FROM `oc_modification` WHERE `xml` like “%关键代码%”

由于这里存的数据被转义过,所以搜索的内容不要带有换行之类的,抓取比较有特点的代码进行查找和修改。修改的时候注意转义的影响哈。当然现在很多MYSQL管理工具这一点做的还是挺好的。建议最好修改插件的ocmod.xml文件,然后重新上传一次。平时插件装了后自己留备份还是有必要的。如果没文件就导出备份再修改。

扩展

上面的示例代码刚好是刚遇到的,所以拿来举例子。授人以鱼不如授人以渔,有的小问题大家花钱又心疼,想自己折腾也未尝不可以,以后还是会提供更多这类比较初级的解决方案给大家。下面另外举例子:

  1. $a = 0;
  2. $value = $key / $a;
  3. //这样可能会提示警告语
  4. if ($a) {
  5.     $value = $key / $a;
  6. }else{
  7.     $value = false;
  8. }
  9. //对$value进行赋值计算结果或者false,也可以赋值预设数字,以便后面进行引用。

上面的方法只是一些示例和排错的技巧,一种思路,具体情况具体分析,但是解决问题要有清晰的思路哈。学会一种技巧少走一些弯路,少花一些钱还是可以的。不过如果要赚钱,舍得花钱找技术开发更适合自己的网站,是很有必要的,花钱减少自己的时间浪费,也少出现一些不必要的麻烦,最重要的是专业的代码和业余的代码还是很大区别的。再者,一个很简单的道理“花钱就是投资”。

phpmyadmin修改登陆超时

如果是本地测试环境,其实没必要那么快的超时登陆,因为有时候可能长时间不去操作,等下又切换过去。然后又要重新登陆,麻烦了点。虽然有的人设置空密码。也是会有麻烦的地方。

一:修改 php.ini

wamp路径:E:\wamp\bin\apache\apache2.4.9\bin\

lnmp路径:/usr/local/php/etc/

  1. ; 搜索
  2. session.gc_maxlifetime
  3. ; 后面的数字改大即可

phpmyadmin-time-phpini

二:修改 config.default.php

wamp路径:!:\wamp\apps\phpmyadmin4**\libraries/

lnmp路径:/home/wwwroot/phpmyadmin/libraries/

或者:/home/wwwroot/default/phpmyadmin/libraries/

  1. // 搜索
  2. $cfg[‘LoginCookieValidity’]
  3. // 把后面的数字改大,不可以大于php.ini配置的数字

phpmyadmin-times-config

php技巧-把RSS内容写入数据库实例教程

有时候,你需要在一个自己另外的网站上调用文章,可是,你又懒得每次去录入更新,如果不在一个主机上,远程连接数据库又不是很好的注意,那么怎么办?抓取!

如果去写个抓取的程序,是比较麻烦的,而且,也可能带来临时的速度影响。好在,可以获取RSS,这样比较方面。

如何用php获取RSS的示例,我前面有写过一篇文章:http://blog.xukhost.com/2819.html

但是,这样的做法,会造成每次打开网站都变慢,而且如果另一个站挂了还会拖慢更多。那么怎么办呢?写个定时脚本,把抓取的数据写入数据库,但是每次打开页面是从数据库查询即可。大家先去看我前面的那个文章。然后得到一些代码,那么这里面有个地方可以利用,看这里:

  1. //构造输出字符串 ,显示的地方,可以自定义!
  2. $rss_str .= “<div class=\”result_list\”><a href='”.$link.“‘ target=_blank>”.$title.“</a></div><div class=\”line\”></div>”;
  3. $is_item = 0;

这个地方是把数据处理了,最后面 echo $rss_str; 的。那么,我们就修改这里,改为SQL语句即可。

  1. $sqlup = “INSERT INTO  `dbname`.`rss_news` (`id`,`title`,`link`) VALUES (”,  ‘”.$title.“‘,  ‘”.$link.“‘)”;
  2. mysql_query($sqlup,$mysql);
  3. $sqlin=mysql_insert_id();

当然了,你需要写一个连接数据库的配置信息,和建立相关的数据表和字段,详情查看我前面写的php教程:

http://blog.xukhost.com/3023.html   and  http://blog.xukhost.com/3064.html

数据库的话,可以执行下面的语句来添加数据表和字段:

  1. CREATE TABLE `sdt_news` (
  2.   `id` int(2) NOT NULL auto_increment,
  3.   `title` varchar(128) NOT NULL,
  4.   `link` varchar(64) NOT NULL,
  5.   UNIQUE KEY `id` (`id`)
  6. ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=11 ;

这里会建立一个 sdt_news 的数据表,同时建立“id、title、link”三个字段。

请自己在本地环境测试该功能,完成后再上线,如果完全看不懂或者部分不懂,请付费联系解决。

QQ  184923973

php技巧-判断浏览器语言跳转不同页面

昨天有一个客户的需求,就是中文浏览器跳转另一个域名,他说自己的opencart买了个插件,插件会根据不同语言跳转不同的二级域名且显示中文,然后要求我帮忙改规则文件让中文的跳转另一个主域名,一开始我没多想,就根据他思路去改规则文件[当时脑袋短路吧],由于那个插件工作原理我不知道,因为我手上没有,又是付费的,所以我只能通过普通的规则文件写法写了重定向定义,可是那样不行,改来改去还是不行,后来我用了下下策,建立个cn子目录来实现,可还是有BUG,默认加载是不存在cn这个二级目录域名的,也就是就算我规则文件改了生效了,也需要点击那个中文的才会进入cn的二级目录[废话好多,进入正题]

于是我查了资料,写了下面的判断语句,自己本地用个php做测试

  1. <?php
  2. $language = substr($_SERVER[‘HTTP_ACCEPT_LANGUAGE’],0,5);
  3. if($language == “zh-cn”) header(“Location: http://cn.abc.com”);
  4. else header(“Location: http://abc.com”);
  5. ?>

可问题来了,在谷歌下不能判断,即使我改为zh也不行,我在火狐下倒是可以的,经过调整测试,和网上的资料,把第一行后面的5改为4,还是不行,不过后来还是搞定了,用下面这样的代码:

  1. <?php
  2. $language = substr($_SERVER[‘HTTP_ACCEPT_LANGUAGE’], 0, 4);
  3. if(preg_match(“/zh-c/i”$language)){
  4. header(“Location: http://cn.abc.com”);
  5. }elseif(preg_match(“/zh/i”$language)){
  6. header(“Location: http://cn.abc.com”);
  7. }else{
  8. header(“Location: http://abc.com”);
  9. }
  10. ?>

但是,我用火狐的时候,出现一个浏览器提示,说有一个不正确的重定向,嗯,于是我去掉了最后一句的else那一句,也就是直接判断,处理,默认情况不处理,当然了,看具体你的需求了,没有的情况不处理,则去掉第七八行,下面是几个语言的示例:

“/en/i” 英语
“/fr/i” 法语
“/de/i” 德语
“/jp/i” 日语
“/ko/i” 朝鲜
“/es/i” 西班牙语
“/sv/i” 瑞典

其他语言可以自己在网上搜索资料替换即可!

上面代码加在index.php 的最前面即可!

language-phpif

看php100视频从零开始学php-php学习第九节[php+mysql的使用]

视频,ppt,示例文件,离线手册下载地址:https://s.yunio.com/2Nlwqu [密码:sdtclass]


最近由于工作忙没有更新,今天来写下关于php100视频第十节,也就是对应本教程第九节–php+mysql的使用!

跟着教程步骤来吧,大纲是:

1、PHP与mysql建立链接

2、如何去执行一个SQL语句

3、两种查询函数array / row区别

4、 其他常用Mysql函数介绍

关于部分内容这里不提及,毕竟这个是配合视频来看的,只拿重点来说明下!

连接数据库的方法:

mysql_connect: 开启 MySQL 链接

mysql_select_db: 打开一个数据库

格式是:

mysql_connect(“主机”, “用户名”, “密码”)

mysql_select_db(“打开数据库”,连接标识符);

如果不特别声明连接标识符,则默认为是上一次打开的连接。

其中,@屏蔽错误,or die 则相反,显示错误,可以定义显示错误的字,下面举例说明:

  1. <?php  
  2. //我在本地建立了一个csuser的用户名,密码是123456,建立了一个cs的数据库  
  3. $sql = @mysql_connect(“localhost”,“csuser”,“123456”);  
  4.   
  5. if($sql){  
  6. echo “成功<br>”;  
  7. //$sql是布尔值,做一个判断判断是否连接成功  
  8.   
  9. $db = mysql_select_db(“cs2”);  
  10.   
  11. if($db){  
  12. echo “db”//cs2改为cs则输出这个  
  13. }else{  
  14. echo “no db<br>”//cs2不存在,所以输出这个  
  15. }  
  16.   
  17. $sql2 = @mysql_connect(“localhost”,“csuser”,“1111”);  
  18. //没有 @ 则输出php错误提示,有则屏蔽错误  
  19.   
  20. $sql3 = @mysql_connect(“localhost”,“csuser”,“11111”or die (“连接错误”);  
  21. //也可以用 or die 来输出当错误的时候输出的提示语句!  
  22. echo 123;  
  23. //or die 错误的时候,后面不会继续跑了  
  24. ?>  

大家可以在自己电脑建立一个数据库,数据库用户,用户密码,然后导入一个数据测试!在上一节已经有相关sql文件可以做测试,可以下去看看!

第三行这里,是连接数据库,也就是打开一个主机!

第五六七行是做了一个判断,是否打开,因为传出来的值是布尔值【PS:真正要用的时候,不用做这个判断,这里是举例说明!】

第九行这里,打开一个数据库文件

第十一至十五行:判断数据库是否连接成功!

第十七行这里,输入了一个错误的密码,但是,由于在语句前面 加了个 @ 则屏蔽了错误提示!

第二十行:用 or die 的方法显示连接错误的语句!

注:or die后面的数据不会再跑!


那么,如何执行一个sql语句呢?在前面有说到一些sql语句的用法,如何执行?

mysql_query (SQL语句 ,连接标识符);

说明:mysql_query用来根据连接标识符向该数据库服务器的当前数据库发送查询,

如果连接标识符默认,则默认为是上一次打开的连接。

返回值:成功后返回一个结果标识符,失败时返回false。

  1. $sql = “SELECT * FROM  test”;  
  2. $result = @ mysql_query($sql$connor die(mysql_error());  

上面这里是一个举例说明,后面的mysql_error()函数是显示错误信息,也就是当错误的使用,用这个echo出数据库的错误信息,方便调试!

  1. <?php  
  2. //打开一个数据库  
  3. $mysql = @mysql_connect(“localhost”,“csuser”,“123456”);  
  4. mysql_select_db(“cs”);  
  5. //执行一个sql语句  
  6. $sql = “INSERT INTO test (id,uid,regdate,remark) values (”,’小草’,now(),’老师’)”;  
  7. mysql_query(“set names ‘GBK'”); //由于直接插入会乱码,因为上面有中文,所以需要定义编码  
  8. mysql_query($sql,$mysql);  
  9. echo mysql_insert_id(); //显示当前插入的ID值  
  10. ?>  

【PS:我弄的是GBK,我建议还是用UTF-8吧,我的文件起初都是GBK保存的,如果打开是乱码用记事本打开然后另存为utf-8】

在PHP里面,utf-8 写成utf8,也就是

  1. mysql_query(“set names ‘utf8′”);  

上面说完语句的使用,那么,查询语句怎么办呢?其实其他语句都是不需要输出的,但是查询的结果需要输出吧?所以下面介绍两个打印输出查询结果的函数:

mysql_fetch_row(result);

PS:简单的说,这个查询出来的是指针的值,也就是你只能通过指针的方法来取值,如果表的数据不多可以使用,表的字段多,要打印一次,然后来找也麻烦,不过,可以使用下面的函数:

mysql_fetch_array(result);

这个和上面的一样,但是这个可以打印字段名称,看下面代码就懂了!

  1. <?php  
  2. //打开一个数据库  
  3. $mysql = @mysql_connect(“localhost”,“csuser”,“123456”);  
  4. mysql_select_db(“cs”);  
  5. mysql_query(“set names ‘GBK'”); //声明编码  
  6.   
  7. $sql = “SELECT * FROM `test` WHERE 1”//查询语句  
  8. $xinxi = mysql_query($sql,$mysql); //把查询结果赋给$xinxi  
  9.   
  10. $shuchu = mysql_fetch_row($xinxi); //row   
  11. //$xinxi 的值用mysql_fetch_row做成数组赋给$shuchu  
  12.   
  13. print_r($shuchu); //打印指针  
  14.   
  15. echo “<br>”;  
  16. echo $shuchu[1]; //输出指针1对应的值  
  17.   
  18. $shuchu2 = mysql_fetch_array($xinxi); //array  
  19. //$xinxi 的值用mysql_fetch_array做成数组赋给$shuchu2  
  20.   
  21. echo “<br>”;  
  22. echo $shuchu2[uid]; //输出关键字uid对应的值  
  23.   
  24. echo mysql_num_rows($xinxi); //输出统计多少条目  
  25. return mysql_close(); //退出当前数据库  
  26.   
  27. ?>  

我们看一下,首先用sql语句查询,用mysql_query来输出值,然后用 mysql_fetch_row来把他做成一个数组,然后赋给$shuchu ,用print_r 打印指针,然后输出指针的值,也就是:

  1. $sql = “SELECT * FROM `test` WHERE 1”//查询语句  
  2. $xinxi = mysql_query($sql,$mysql); //把查询结果赋给$xinxi  
  3.   
  4. $shuchu = mysql_fetch_row($xinxi);   
  5.   
  6. print_r($shuchu); //打印指针  
  7.   
  8. echo $shuchu[1]; //输出指针1对应的值  

在表的字段不多的时候,可以这样,但是多的时候,这样还是比较麻烦的,所以可以这样:

  1. $sql = “SELECT * FROM `test` WHERE 1”;     
  2. $xinxi = mysql_query($sql,$mysql);  
  3.   
  4. $shuchu2 = mysql_fetch_array($xinxi);   
  5.   
  6. echo $shuchu2[uid];   

是不是简化了,方便了很多呢?看情况用吧!


其他常用mysql函数介绍:

mysql_num_rows  用于计算查询结果中所得行的数目 //上面举例了

mysql_insert_id 传回最后一次使用 INSERT 指令的 ID。//上面举例了

mysql_tablename 取得数据库名称

mysql_error   返回错误信息 //上面举例了

mysql_close 关闭 MySQL 链接 //上面举例了

OK,基础知识就到这里结束了!其实还是很简单的!但是要精通,就需要多写多练习代码了!

php-php+mysql-ljcw

 

看php100视频从零开始学php-php学习第八节[数据库基础语法]

视频,ppt,示例文件下载地址:https://s.yunio.com/2Nlwqu [密码:sdtclass]


 

上一节说了mysql数据库的基本认识,这一节来讲讲mysql的一些基本语法和例子

目录:

1、SELECT 查询语句和条件语句

2、排序,分组,指针查询,计算

3、Insert 插入语句

4、Update 更新语句

5、Delete  删除语句 


 SELECT 查询语句和条件语句:

SELECT 查询字段 FROM 表明 WHERE 条件

查询字段:可以使用通配符 * , 字段名 ,字段别名

表名:数据库表名 , 表名

常用条件:

=  代表  等于

<>  代表  不等于

in  代表  包含

not in  代表  不包含

like  代表  区配

BETWEEN  在范围

NOT BETWEEN  不在范围

< >  大于小于

条件运算 and ,or ,( )

OK,下面来举例子说明下

  1. SELECT * FROM `test` WHERE 1;  
  2. SELECT id,uid FROM `test` WHERE 1;  
  3. SELECT id,uid FROM cs.`test` WHERE 1;  
  4. SELECT regdate as reg FROM `test` WHERE 1;  

第一个是默认的查询test表中的所有字段,其实你打开数据库进入某一个表的架构就会看到这个sql语句了

第二个是查询test表中的id和uid字段

第三个是当有多个数据库时,可以指定数据库查询字段,指定了cs数据库中,test表中的id和uid字段

第四个是查询的时候,给regdate字段使用别名reg

  1. SELECT * FROM `test` WHERE id=1;  
  2. SELECT * FROM `test` WHERE id<>1;  
  3. SELECT * FROM `test` WHERE id in (1,3);  
  4. SELECT * FROM `test` WHERE id not in (1,3);  
  5. SELECT * FROM `test` WHERE `uid` like “%张%”;  
  6. SELECT * FROM `test` WHERE id between 1 and 3;  
  7. SELECT * FROM `test` WHERE id not between 1 and 3;  
  8. SELECT * FROM `test` WHERE id>1;  
  9. SELECT * FROM `test` WHERE id<3;  

第一个是查询test数据表中,id的值等于1的对应数据

第二个是查询test数据表中,id的值不等于1的对应数据

第三个是查询test数据表中,id的值包含1和3的对应数据

第四个是查询test数据表中,id的值除了1和3之外的对应数据

第五个是查询test数据表中,uid的值包含张的数据,百分号是区配符,前后区配,也就是前面和后面可以带任意字

第六个是查询test数据表中,id的值的范围是1到3的对应数据

第七个是查询test数据表中,id的值的范围是1到3之外的其他对应数据

第八个第九个分别是查询test数据表中id大于1的数据,和id小于3的数据

  1. SELECT * FROM `test` WHERE `regdate`=“2008-07-02” and `remark`=“学生”;  
  2. SELECT * FROM `test` WHERE id=2 or id=4;  

第一个是搜索注册日期在2008年7月2日的并且职称是学生的数据

第二个是搜索id等于3或者id=4的数据

上面的语法和举例和说明都列出来了,剩下的是大家自己实践操作,操作下就明白了,网盘有SQL文件


排序,分组,指针查询:

分组语句  group by 字段

排序语句  order by 字段 ASC / DESC

指针查询  limit 初始值,结束值

  1. SELECT * FROM `test` group by `remark`;  
  2. SELECT * FROM `test` order by `regdate` ASC;  
  3. SELECT * FROM `test` order by `regdate`; 
  4. SELECT * FROM `test` order by `regdate` DESC;  
  5. SELECT * FROM `test` order by `regdate` DESC, id ASC;  
  6. SELECT * FROM `test` limit 1,4 ; 
  7. SELECT * FROM `test` limit 4 ;

第一句是:分组统计看看有多少种职称,查询remark对应值有哪些不同

第二句是:根据注册日期排序,而不是原来默认的ID排序

第三局和第二句一样,不写ASC也是顺序排序

第四局是:根据注册日期倒序排序

第五句是:注册日期倒序排序,ID正序排序

第六句是:id的指针从1到4,但是忽略第一个值,也就是显示2-4

第七句是:id的指针从0到4,但是忽略第一个值,也就是显示1-4

OK,还是要大家去数据库操作才会更明白,到网盘下数据操作!

如果三个语句要一起使用的话,顺序是group by 在其他两个前面,order by在limit前面,limit在有前面两个条件的时候,放最后面,在使用者三个的时候,不需要WHERE


计算:

COUNT(*) 统计函数

MAX(*) 最大值函数

MIN (*) 最小值函数

AVG(*) 平均值函数

SUM(*) 累计值函数(∑)

  1. SELECT count(*) FROM `test` WHERE 1 ;
  2. SELECT max(id) FROM `test` WHERE 1 ;
  3. SELECT min(id) FROM `test` WHERE 1 ;
  4. SELECT avg(id) FROM `test` WHERE 1 ;
  5. SELECT sum(id) FROM `test` WHERE 1 ; 

第一个是:统计值,统计表中有多少字段

第二个是:最大值,查询id对应的最大数值

第三个是:最小值,查询id对应的最小数值

第四个是:平均值,查询id对应的值平均值,由于是4个,所以是2.5000

第五个是:累计值,查询id对应值的累计值,就是累加起来的值,1+2+3+4=10

计算基本讲到这里,大家多试试就懂了


Insert 插入语句

有两种,一种是:insert into 表名 (字段…,…) values(值…,…)

另一种是:insert into 表名 values(值…,…)

PS:建议用第一种,避免忘了哪个字段需要对应值而导致出什么问题

注意:插入时须考虑清楚字段类型避免插入后出现缺值,乱码现象

  1. insert into test (`id`,`uid`,`regdate`,`remark`) values (,’sd’,now(),’工人’)  
  2.   
  3. insert into test values (,’sd’,now(),’工人’)  

在test中,插入一个数据,id不用填,因为默认自动递增排序,uid填写名字,时间可以使用时间函数来代表现在的时间!职称写职工人或者学生

update更新语句

格式:UPDATE 表名 SET 字段 = 值 WHERE 条件 limit  【limit可忽略】

可以使用上面的查询语句中使用到的条件,如 = <> in和not in等等

  1. update test set remark=’学生’ where uid=’sd’  

更新test表中,uid字段对应值是sd的表,把职称改为学生

delete删除语句

不建议使用,格式:DELETE  FROM 表名 WHERE 条件 limit

同样和更新语句一样,可以使用查询语句中的条件那些

  1. delete from test where id=2  

删除test表中,id的值是2的那个字段

OK啦,基本的都讲了,其实还是很简单的,记住一些单词就可以了,记不住抄下来,做个笔记,要用的时候看看,用久了就记住了!

php-mysql-02demo

php学习扩展-根据所学知识做一个九九乘法表

视频,php手册,ppt,示例文件下载地址:https://s.yunio.com/2Nlwqu [密码:sdtclass]


 

今天由于时间关系不讲第二节数据库内容了,来扩展应用一下以前学的知识点!

写一个九九乘法表,要怎么写呢?大家可以想一下!

首先,九九乘法表里面是1×1=1,1×2=2这样以此类推,那么,你们应该就想到,有个1234在里面,对,没错,需要循环,那么,我们需要写一个fot循环语句!如下:

  1. <?php  
  2.   
  3. for($a=1;$a<10;++$a){  
  4. }  
  5.   
  6. ?>  

上面定义从1开始,到9,也就是小于10,用递增,每次+1,所以用上面的代码echo出来就是1 2 3 — 9 这样

OK,那么,我们需要的九九乘法表有三个数字,两个符号啊,怎么办呢?我们先写第二串数字

  1. <?php  
  2.   
  3. for($a=1;$a<10;++$a){  
  4. for($b=1;$b<10;++$b){  
  5. echo “$a x $b = “;  
  6. }  
  7. }  
  8.   
  9. ?>  

上面这里echo出来的效果就是1 x 1   1 x 2这样循环到9 x 9 大家可以看一下,$a都是从1开始,小于10,也就是到9这里,然后每次的+1 递增,外回圈从1 – 9 这样, 1内的for循环从1 – 9 ,也就是达到了1 x 1到9 x 9这样,其实还可以这样写!

  1. <?php  
  2.   
  3. for($a=1;$a<=9;++$a){  
  4. for($b=1;$b<=9;++$b){  
  5. echo “$a x $b = “;  
  6. }  
  7. }  
  8.   
  9. ?>  

好,那么,我们需要在1 x 9 和 2 x 9这样的后面换行,怎么办呢?后面的9是内回圈的值,所以,我们需要写一个if语句!

  1. <?php  
  2.   
  3. for($a=1;$a<=9;++$a){  
  4. for($b=1;$b<=9;++$b){  
  5. echo “$a x $b = “;  
  6. if($b==9) echo “<br>”;  
  7. }  
  8. }  
  9.   
  10. ?>  

if语句判断了,当$b 也就是内回圈的值等于9的时候,输出<br>回车!

那么,是不是OK了呢?但是怎么计算结果呢?所以这里需要做一个运算!由于前面的教程我们都没说乘除法运算,其实可以查手册,也可以百度下如何做运算,其实就是 a*b这样简单,先举例如下:

  1. <?php  
  2.   
  3. $c=$a*$b;  
  4.   
  5. ?>  

我们把$a乘以$b的值赋给了$c,那么,我们只要把$c的值,写在=后面,就可以了!

  1. <?php  
  2.   
  3. for($a=1;$a<=9;++$a){  
  4. for($b=1;$b<=9;++$b){  
  5. $c=$a*$b;  
  6. echo “$a x $b = $c, “;  
  7. if($b==9) echo “<br>”;  
  8. }  
  9. }  
  10.   
  11. ?>  

OK,我为了1 x 1 = 1 后面有个逗号分开,在echo出来的后面写了个 , 号,这样可以分割开,比较好看!当然你可以扩展的写上html代码等等,这里不做讨论,大家自己扩展研究,激发自己想象力吧!

效果如图!

php-kuozhan-01

看php100视频从零开始学php-php学习第七节[数据库]

视频,ppt,示例文件下载地址:https://s.yunio.com/2Nlwqu [密码:sdtclass]


说数据库之前,我们总结下前面的php学习,前面的php都是比较基础的部分,那么,很多人说看了不懂,其实看是很难懂的,我为什么写文字,附带视频,ppt,示例文件?因为需要结合学习!首先先看视频,然后看我的文字教程,举例方面有所出入,因为例子不同更好理解,同一个例子的话,很难有扩展性的理解,所以,我举了不同的例子放在示例文件里面,就是这个原因!配合PPT,PPT方面是一部分笔记,大家抄下来,另外,视频讲解的时候,你们也可以记录一些重要的信息,PPT里面只是一小部分,所以干嘛要你们看视频呢?看视频是先预热,但是你要自己写代码测试!所以我提供了示例文件,而且示例文件是另外的例子,前面也说了那也更好的扩展理解!

所以正确的学习php方式是:视频+ppt+示例文件+笔记+练习

前面我都提供了,练习怎么弄呢?推荐下个appserv,我是用这个,当然还有很多其他的,安装后在本地建立php文件做测试,appserv的安装,有教程的,网上搜索一大把呢!大家要学会百度一下!

另外,php100第一节的视频我没传,大家可以自己去网上看看,或者php100官网看下第一节视频的php介绍,内容比较普通,所以我没有引用过来写文章,也没必要写!

这一节没有示例文件,因为这一节的内容是讲下数据库的初步认识,下面是正文:

数据库有很多种,什么mysql,mssql,还有很多啦,反正我这里不介绍,有兴趣自己百度,视频教程里面也讲了很多,我抓重点写一下概述,当是写给大家的笔记,其他我不多说,自己看视频了解吧,我文字描述那么多还不如你们看视频来的快,因为这一节没有示例【其实有,在数据库里面用数据库命令,这个以后慢慢深入】

数据库的管理工具也有很多,有客户端的,web端的,客户端的比较安全,高效,web端的比较方便,随时可以管理,mysql数据库默认端口是3306,默认安装最高用户是root,安装时候没有提示输入密码的情况下,密码默认为空,也就是不输入,然后进去改密码!当然现在很多安装mysql的,都是需要你输入密码的!

数据库的类型分为五种,如下:

整数型:TINYINT(0-255位数),SMALLINT,INT,BIGINT 【从左到右依次是从小到大的数据存储类型】

扩展知识:

TINYINT:1字节 非常小的正整数,带符号:-128~127,不带符号:0~255
SMALLINT:2字节 小整数,带符号:-32768~32767,不带符号:0~65535
MEDIUMINT:3字节 中等大小的整数,带符号:-8388608~8388607,不带符号:0~16777215
INT:4字节 标准整数,带符号:-2147483648~2147483647,不带符号:0~4294967295
BIGINT:8字节 大整数,带符号:-9223372036854775808~9233372036854775807,不带符 号:0~18446744073709551615

小数型:FLOAT,DOUBLE,DECIMAL 【从左到右依次是从小到大的数据存储类型】

扩展知识:

FLOAT:4字节 单精度浮点数,最小非零值:+-1.175494351E-38,最大非零值:+-3.402823466E+38
DOUBLE:8字节 双精度浮点数,最小非零值:+-2.2250738585072014E-308,最大非零值:+-1.7976931348623157E+308
DECIMAL:M+2字节 以字符串形式表示的浮点数,它的取值范围可变,由M和D的值决定。其中M代表总的位数,D代表小数点后的位数

字符型:CHAR,VARCHAR 【CHAR是固定型,而VARCHAR是弹性型】

扩展知识:

CHAR[(M)]M字节 M字节
VARCHAR[(M)]M字节 L+1字节

日期型:DATETIME,DATE,TIMESTAMP

扩展知识:

DATETIME 是包括日期,时间的 [DATETIME1000-01-01 00:00:00~9999-12-31 23:59:59 字节:8字节 0000-00-00 00:00:00]

DATE 是存储日期,不包括时间的 ,[1000-01-01~9999-12-31 字节:3字节(MySQL3.23版以前是4字节 ) 0000-00-00]

TIMESTAMP 这个以数字存储,精确比较高的 ,[P19700101000000~字节  4字节]

备注型:TINYTEXT,TEXT,LONGTEXT 【和字符型的区别的话,备注型的长度比较大】

扩展:

TINYTEXT:2^8-1字节 L+1字节

TEXT2^16-1字节 L+2

LONGTEXT2^32-1字节 L+4

上面这里介绍的都是比较基本常用的数据库类型,还有一些其他的,大家可以百度一下mysql数据库类型!

下面来说一些比较常用的数据库命令:

创建数据库命令:CREATE TABLE

删除一个数据库命令:DROP  TABLE

插入一个字段命令:ALTER TABLE  `表` ADD `新字段` … AFTER `原字段`

删除一个字段命令:ALTER TABLE  `表` DROP `原字段`

修改一个字段名称:RENAME TABLE `原字段` TO `新字段`

PS:特别注意,上面不是单引号,也不是双引号,是键盘上ESC下面那排数字键中数字1前面的那个小斜点,不是引号哦!

其中,插入字段中后面我用橙色标识出来的“… AFTER `原字段” 意思是,比如你要插入到某个字段后面,而不是默认插入到最后面的话,可以用这样的语句来实现插入到某个字段后面

举例:【创建一个“SDT”的字段,类型为TEXT,NOT NULL不能为恐,增加在“uid”字段之后】

  1. ALTER TABLE  `test` ADD  `SDT` TEXT NOT NULL AFTER  `uid` ;  

下面来举例一个mysql语句来解读:

  1. CREATE TABLE `test` (  
  2.   `id`  int(10)  NOT NULL auto_increment,  
  3.   `uid`     varchar(10) NOT NULL  default ‘0’,  
  4.   `regdate`  date NOT NULL,  
  5.   `remark`    text  NULL,  
  6.    PRIMARY KEY  (`id`)  
  7. )  

大家在自己数据库里面试一试就知道了,这里我来解释一下

第一行定义创建一个表

第二行定义创建一个名为“id”的字段,字段类型用int,10字节,NOT NULL就是不能为空,auto_increment呢是定义从1开始递增,每条递增+1,当然了,auto_increment的默认值也可以定义从其他数字开始,比如“ALTER TABLE Persons AUTO_INCREMENT=100”

第三行定义创建一个名为“uid”的字段,字段类型是varchar,10字节,NOT NULL就是不能为空,默认值是:0

第四行定义创建一个名为“regdate”的字段,字段类型是date,NOT NULL就是不能为空

第五行定义创建一个名为“remark”的字段,字段类型是text ,NULL意思是可以为空

第六行定义了一“id”字段为主键关键帧

那个代码大家在数据库里面建立一个数据库后在sql命令行里面测试就知道了!

php-no.7-mysql-demo

OK!今天的课程就到这里!