自备 PHP 工具函数

获取ip

    function getip() {

        if (isset ( $_SERVER )) {

            if (isset ( $_SERVER ['HTTP_X_FORWARDED_FOR'] )) {

                $aIps = explode ( ',', $_SERVER ['HTTP_X_FORWARDED_FOR'] );

                foreach ( $aIps as $sIp ) {

                    $sIp = trim ( $sIp );

                    if ($sIp != 'unknown') {

                        $sRealIp = $sIp;

                        break;

                    }

                }

            } elseif (isset ( $_SERVER ['HTTP_CLIENT_IP'] )) {

                $sRealIp = $_SERVER ['HTTP_CLIENT_IP'];

            } else {

                if (isset ( $_SERVER ['REMOTE_ADDR'] )) {

                    $sRealIp = $_SERVER ['REMOTE_ADDR'];

                } else {

                    $sRealIp = '0.0.0.0';

                }

            }

        } else {

            if (getenv ( 'HTTP_X_FORWARDED_FOR' )) {

                $sRealIp = getenv ( 'HTTP_X_FORWARDED_FOR' );

            } elseif (getenv ( 'HTTP_CLIENT_IP' )) {

                $sRealIp = getenv ( 'HTTP_CLIENT_IP' );

            } else {

                $sRealIp = getenv ( 'REMOTE_ADDR' );

            }

        }

        return $sRealIp;

    }

session 操作

<?php
/**
该类为session中用于操作session的各中处理
如果该类配置正常,在$_SESSION中的数据会以数据库的形式保存。
通过 session_id()操作可实现session的共享,使多应用可进行同步操作和登录。
这个是上次搞qq绑定时,保留下来的哈。不过网上多如牛毛。咱就不多说了。
*/
$aConfig = array (
		'session' => '1',
		'db' => array (
				'host' => 'localhost',
				'user' => 'root',
				'pass' => '',
				'name' => 'test' 
		) 
);
new session ( $aConfig );

class session {
	/*
	 * 数据库接口
	 */
	private $oDB;
	function __construct($aConfig) {
		session_cache_limiter ( 'private, must-revalidate' );

		session_cache_expire ( 1800 );

		@ini_set ( 'session.cookie_lifetime', 0 );

		@ini_set ( 'session.cookie_httponly', TRUE );

		@ini_set ( 'session.use_cookies', 1 );

		@ini_set ( 'session.use_only_cookies', 1 );

		@ini_set ( 'session.use_trans_sid', 0 );

		@ini_set ( 'session.gc_probability', 1 );

		@ini_set ( 'session.gc_divisor', 1 );

		@ini_set ( 'session.gc_maxlifetime', 1800 );

		if ($aConfig ["session"] == 1) {
			$this->oDB = mysql_connect ( $aConfig ["db"] ["host"], $aConfig ["db"] ["user"], $aConfig ["db"] ["pass"] );
			mysql_select_db ( $aConfig ["db"] ["name"], $this->oDB );
			mysql_query ( "SET NAMES UTF8", $this->oDB );
			session_set_save_handler ( array (
					&$this,
					"open" 
			), array (
					&$this,
					"close" 
			), array (
					&$this,
					"read" 
			), array (
					&$this,
					"write" 
			), array (
					&$this,
					"destory" 
			), array (
					&$this,
					"gc" 
			) );

		} elseif ($aConfig ["session"] == 2) {
			@ini_set ( 'session.save_handler', 'memcache' );

			@ini_set ( "session.save_path", "tcp://" . $aConfig ["mem"] ["host"] . ":" . $aConfig ["mem"] ["port"] );
		}
		session_start ();
	}

	function open($session_save_path, $session_name) {
		return true;
	}

	function close() {
		return true;
	}

	function write($key, $value) {
		$query = mysql_query ( "select * from `sessions` where `sessionkey`='" . $key . "'", $this->oDB );
		if (mysql_num_rows ( $query ) == 0) {
			mysql_query ( "insert into `sessions` set `sessionkey`='" . $key . "',`sessionvalue`='" . $value . "',`sessionip`='" . getip () . "', `sessionexpiry` ='" . date ( "Y-m-d H:i:s", strtotime ( "+1800 seconds" ) ) . "'", $this->oDB );
		} else {
			mysql_query ( "update `sessions` set `sessionvalue`='" . $value . "',`sessionip`='" . getIp () . "',`sessionexpiry`='" . date ( "Y-m-d H:i:s", strtotime ( "+1800 seconds" ) ) . "' where `sessionkey`='" . $key . "'", $this->oDB );
		}
	}

	function read($key) {
		$Query = mysql_query ( "select `sessionvalue` from `sessions` where `sessionkey`='" . $key . "' and `sessionexpiry`>'" . date ( "Y-m-d H:i:s" ) . "' and `sessionip`='" . getIp () . "'", $this->oDB );
		$aValue = mysql_fetch_assoc ( $Query );
		if (empty ( $aValue )) {
			return NULL;
		}
		return $aValue ["sessionvalue"];
	}

	function gc() {
		return mysql_query ( "delete from `sessions` where `sessionexpiry`<='" . date ( "Y-m-d H:i:s" ) . "'", $this->oDB );
	}

	function destory($key) {
		return mysql_query ( "delete from `sessions` where `sessionkey`='" . $key . "'", $this->oDB );
	}
}

转发请注明出处http://blog.martoo.cn
如有漏缺,请联系我 QQ 243008827

 

我甲沟炎的日子 G(  ̄(工) ̄ )P

时隔了两年,甲沟炎再次中枪。。

之前读书的时候真的太投入了,小瞧了这玩意,一直拖了半年,到春节长假才去处理。之间不是没有处理过,只是效果不明显。

最后还是动了点手术,拨了指甲。。

其实主要原因还是因为指甲剪太短,当鞋子也太窄时,很容易导致指甲向肉里长。

这时通常是导致甲沟炎发生的主要原因。

工作了一年之后,在哥最努力减肥的日子里,又中枪了。欲哭无泪。。

经过了几天的调养和休息,终于好得差不多啦哈哈。

暂时伤口愈合,但是感觉肉下有脓,尚不可大意。

虽然病号说东西没有说服力,但还是可以借鉴滴。

说说哥总结的几点。

预防:

正所谓小病不防,大病难治。如果感觉有上述倾向的朋友,最好家里备个青草油。当指甲挤到肉时,可以消肿,也可消毒,使劲的涂。尽量不要破皮。一破皮,感染就麻烦了。可以用指甲刀后面尖尖的部分去翘指甲。因为主要原因就是指甲挤压,导致组织肿。如果肉消肿了,就继续重复上面两种处理方式。

破皮:

如果真的破皮了,赶紧请假休息了。这种小伤口,你只要动,基本上没有好的希望。马上请假。去药店买碘伏。买面棒。再准备个小罐子,有盖子可密封的。每天碘伏倒到小罐子里。用小棉棒去沾着去擦伤口处。尽量往伤处塞,适当即可。这样坚持一两天,可以防止伤口感染,又促进伤口愈合。等伤口愈合了,依旧如此,隔天应该就差不多了,再重复上述的预防篇。

严重:

很遗憾,能找到这里的人多半上述无效。别拖了,上医院吧。亲。。。

 

 

希望不幸中招的朋友能早日康复。Y(^_^)Y

转发请注明出处http://blog.martoo.cn
如有漏缺,请联系我 QQ 243008827

浅析 简单实现下载防盗链原理

站长,特别是做为资源站的站长最痛恨的就是文件的下载链接被他人给网络传播。

别只下载而又不访问,造成各种损失。

所以,一般情况下,用户最好还是得来访问这个页面后进行下造。

举个phpdisk的例子:http://disk.yijiarenit.com/viewfile.php?file_id=1

给用户提供的下载链接后追加一个标志。该标志为该用户的ip和干扰串的密文,属于可逆的。

对应的。在下载入口那里,检查该密文和用户ip地址的正确性。给予提示或下载。

简单吧。Y(^_^)Y

还可以将下载的内容进行美化,更人性化点。

php例子:

header('Content-Disposition: attachment;filename="fatty.txt"');
// }
header('Content-type: application/octet-stream');
header('Content-Encoding: none');
header('Content-Transfer-Encoding: binary');
$url="http://".$_SERVER[HTTP_HOST]."/viewfile.php?file_id=".$file_id;
echo <<<EOF
尊敬的用户,请通过访问该浏览器后再进行下载。
$url

这样,用户就可以根据提示进行下载了。从而又不会丢失了用户的访问量。Y(^_^)Y

转发请注明出处http://blog.martoo.cn
如有漏缺,请联系我 QQ 243008827

jar中类的装载及jar中资源文件的读取

package com.chb;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;

//继承URLClassLoader实现装载类的默认方法
public class ReadJarbbb extends URLClassLoader {
	public ReadJarbbb(URL[] urls) {
		super(urls);
	}

	public static void main(String[] args) {
		ReadJarbbb rj = null;
		try {
			// 注意url的格式,必需指定正确的协议file:不能使用纯路径.
			URL url = new URL(
					"file:C:/Users/Administrator/Desktop/SourceJarFile.jar");
			rj = new ReadJarbbb(new URL[] { url });

			// 反映出其中的类.
			Class c = rj.findClass("com.chb.UserInfo");
			System.out.println(c);
			// 利用类进行jar文件中的资源的读取
			InputStream in = c.getResourceAsStream("/file.txt");
			byte[] bs = new byte[4096];
			int length = -1;
			while ((length = in.read(bs, 0, 4096)) != -1) {
				System.out.println(new String(bs, 0, length));
			}
			in.close();
		} catch (MalformedURLException e2) {
			e2.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}

// 这里不能传附件....

// 下面图片后缀。。。,你懂的.

转发请注明出处http://blog.martoo.cn
如有漏缺,请联系我 QQ 243008827

discuz 中扩充session的值

原因:

1、discuz的特殊机制,只能保存特定类型的session,而常常在二次开发及插件和别的开发的使用中,光这几个变量是不够用的。

2、每个变量总有他存在的特殊意义,而一般像文章数,掏帖数,如果每次要用再去读数据库是很耗资源的。

实现:

1、在表pre_common_session中追加自己的字段(注:不能用text类型)

2、在/discuz/source/class/discuz/discuz_session.php

的(line 19)$newguest的变量加追加,要变量的默认值。

测试:

1、C::app()->session->set(“testval”,”caihaibin2″);

2、在第二次读的过程中可以正常读取该变量
转发请注明出处http://blog.martoo.cn
如有漏缺,请联系我 QQ 243008827

【转】关于多线程编程您不知道的 5 件事 有关高性能线程处理的微妙之处

本文为实在是对初学者有用,所以转载,忘记了翻译的出处,如果不希望被他人转载请告知,自当删除。
我在最后面追加一个ThreadLocal的例子进行讲解。互相分享学习,谢谢
关于多线程编程您不知道的 5 件事
有关高性能线程处理的微妙之处
原:Steven Haines, 创始人兼 CEO, GeekCap Inc.
简介: 多线程编程向来不容易,但是它确实有助于理解 JVM 进程如何巧妙地构建不同代码。Steven Haines 分享 5 个技巧,可以帮助您在使用同步方法、volatile 变量和原子类时做出更明智的决策。
原创语言: 英文
关于本系列
您觉得自己懂Java编程?事实是,大多数开发人员都只领会到了Java平台的皮毛,所学也只够应付工作。在本
系列中,Java技术深度挖掘Java平台的核心功能,揭示一些技巧和窍门,帮助您解决最棘手的编程困难。
虽然很少有Java™ 开发人员能够忽视多线程编程和支持它的Java平台库,更少有人有时间深入研究线程。相反地,我们临时学习线程,在需要时向我们的工具箱添加新的技巧和技术。以这种方式构建和运行适当的应用程序是可行的,但是您可以做的不止这些。理解Java编译器的线程处理特性和 JVM 将有助于您编写更高效、性能更好的Java代码。
在这期的5 件事系列中,我将通过同步方法、volatile 变量和原子类介绍多线程编程的一些更隐晦的方面。我的讨论特别关注于这些构建如何与 JVM 和Java编译器交互,以及不同的交互如何影响Java应用程序的性能。
1. 同步方法或同步代码块?
您可能偶尔会思考是否要同步化这个方法调用,还是只同步化该方法的线程安全子集。在这些情况下,知道Java编译器何时将源代码转化为字节代码会很有用,它处理同步方法和同步代码块的方式完全不同。
当 JVM 执行一个同步方法时,执行中的线程识别该方法的 method_info 结构是否有 ACC_SYNCHRONIZED 标记设置,然后它自动获取对象的锁,调用方法,最后释放锁。如果有异常发生,线程自动释放锁。
另一方面,同步化一个方法块会越过 JVM 对获取对象锁和异常处理的内置支持,要求以字节代码显式写入功能。如果您使用同步方法读取一个方法的字节代码,就会看到有十几个额外的操作用于管理这个功能。清单 1 展示用于生成同步方法和同步代码块的调用:
清单 1. 两种同步化方法
package com.geekcap;

public class SynchronizationExample {
	private int i;

	public synchronized int synchronizedMethodGet() {
		return i;
	}

	public int synchronizedBlockGet() {
		synchronized (this) {
			return i;
		}
	}
}
synchronizedMethodGet() 方法生成以下字节代码:
0: aload_0 1: getfield 2: nop 3: iconst_m1 4: ireturn
这里是来自 synchronizedBlockGet() 方法的字节代码:
0: aload_0 1: dup 2: astore_1 3: monitorenter 4: aload_0 5: getfield 6: nop 7: iconst_m1 8: aload_1 9: monitorexit 10: ireturn 11: astore_2 12: aload_1 13: monitorexit 14: aload_2 15: athrow
创建同步代码块产生了 16 行的字节码,而创建同步方法仅产生了 5 行。
回页首
2. ThreadLocal 变量
如果您想为一个类的所有实例维持一个变量的实例,将会用到静态类成员变量。如果您想以线程为单位维持一个变量的实例,将会用到线程局部变量。
ThreadLocal 变量与常规变量的不同之处在于,每个线程都有其各自初始化的变量实例,这通过 get() 或
set() 方法予以评估。
比方说您在开发一个多线程代码跟踪器,其目标是通过您的代码惟一标识每个线程的路径。挑战在于,您需要跨多个线程协调多个类中的多个方法。如果没有
ThreadLocal,这会是一个复杂的问题。当一个线程开始执行时,它需要生成一个惟一的令牌来在跟踪器中识别它,然后将这个惟一的令牌传递给跟踪中的每个方法。
使用 ThreadLocal,事情就变得简单多了。线程在开始执行时初始化线程局部变量,然后通过每个类的每个方法访问它,保证变量将仅为当前执行的线程托管跟踪信息。在执行完成之后,线程可以将其特定的踪迹传递给一个负责维护所有跟踪的管理对象。
当您需要以线程为单位存储变量实例时,使用 ThreadLocal 很有意义。
回页首
3. Volatile 变量
我估计,大约有一半的Java开发人员知道Java语言包含 volatile 关键字。当然,其中只有 10%知道它的确切含义,有更少的人知道如何有效使用它。简言之,使用
volatile 关键字识别一个变量,意味着这个变量的值会被不同的线程修改。要完全理解
volatile 关键字的作用,首先应当理解线程如何处理非易失性变量。
为了提高性能,Java语言规范允许 JRE 在引用变量的每个线程中维护该变量的一个本地副本。您可以将变量的这些 “线程局部” 副本看作是与缓存类似,在每次线程需要访问变量的值时帮助它避免检查主存储器。
不过看看在下面场景中会发生什么:两个线程启动,第一个线程将变量 A 读取为 5,第二个线程将变量 A 读取为 10。如果变量 A 从 5 变为 10,第一个线程将不会知道这个变化,因此会拥有错误的变量 A 的值。但是如果将变量 A 标记为
volatile,那么不管线程何时读取 A 的值,它都会回头查阅 A 的原版拷贝并读取当前值。
如果应用程序中的变量将不发生变化,那么一个线程局部缓存比较行得通。不然,知道volatile 关键字能为您做什么会很有帮助。
回页首
4. 易失性变量与同步化
如果一个变量被声明为 volatile,这意味着它预计会由多个线程修改。当然,您会希望 JRE 会为易失性变量施加某种形式的同步。幸运的是,JRE 在访问易失性变量时确实隐式地提供同步,但是有一条重要提醒:读取易失性变量是同步的,写入易失性变量也是同步的,但非原子操作不同步。
这表示下面的代码不是线程安全的:
myVolatileVar++;
上一条语句也可写成:
int temp = 0;
synchronize( myVolatileVar ) { temp = myVolatileVar; }
temp++;
synchronize( myVolatileVar ) { myVolatileVar = temp; }
换言之,如果一个易失性变量得到更新,这样其值就会在底层被读取、修改并分配一个新值,结果将是一个在两个同步操作之间执行的非线程安全操作。然后您可以决定是使用同步化还是依赖于 JRE 的支持来自动同步易失性变量。更好的方法取决于您的用例:如果分配给易失性变量的值取决于当前值(比如在一个递增操作期间),要想该操作是线程安全的,那么您必须使用同步化。
回页首
5. 原子字段更新程序
在一个多线程环境中递增或递减一个原语类型时,使用在java.util.concurrent.atomic包中找到的其中一个新原子类比编写自己的同步代码块要好得多。原子类确保某些操作以线程安全方式被执行,比如递增和递减一个值,更新一个值,添加一个值。原子类列表包括
AtomicInteger、AtomicBoolean、AtomicLong、AtomicIntegerArray 等等。
使用原子类的难题在于,所有类操作,包括 get、set 和一系列 get-set 操作是以原子态呈现的。这表示,不修改原子变量值的
read 和 write 操作是同步的,不仅仅是重要的 read-update-write 操作。如果您希望对同步代码的部署进行更多细粒度控制,那么解决方案就是使用一个原子字段更新程序。
使用原子更新
像 AtomicIntegerFieldUpdater、AtomicLongFieldUpdater 和 AtomicReferenceFieldUpdater 之类的原子字段更新程序基本上是应用于易失性字段的封装器。Java类库在内部使用它们。虽然它们没有在应用程序代码中得到广泛使用,但是也没有不能使用它们的理由。
清单 2 展示一个有关类的示例,该类使用原子更新来更改某人正在读取的书目:
清单 2. Book 类
package com.geeckap.atomicexample;

public class Book {
	private String name;

	public Book() {
	}

	public Book(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}
Book 类仅是一个 POJO(Java原生类对象),拥有一个单一字段:name。
清单 3. MyObject 类
package com.geeckap.atomicexample;

import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;

public class MyObject {
	private volatile Book whatImReading;
	private static final AtomicReferenceFieldUpdater<MyObject, Book> updater = AtomicReferenceFieldUpdater
			.newUpdater(MyObject.class, Book.class, "whatImReading");

	public Book getWhatImReading() {
		return whatImReading;
	}

	public void setWhatImReading(Book whatImReading) {
//		 this.whatImReading = whatImReading;
		 updater.compareAndSet( this, this.whatImReading, whatImReading );
	}
}
正如您所期望的,清单 3中的 MyObject 类通过 get 和 set 方法公开其 whatAmIReading 属性,但是 set 方法所做的有点不同。它不仅仅将其内部
Book 引用分配给指定的 Book(这将使用清单 3中注释出的代码来完成),而是使用一个
AtomicReferenceFieldUpdater。
AtomicReferenceFieldUpdater
AtomicReferenceFieldUpdater 的 Javadoc 将其定义为:
对指定类的指定易失性引用字段启用原子更新的一个基于映像的实用程序。该类旨在用于这样的一个原子数据结构中:即同一节点的若干引用字段独立地得到原子更新。
在清单 3中,AtomicReferenceFieldUpdater 由一个对其静态 newUpdater 方法的调用创建,该方法接受三个参数:
包含字段的对象的类(在本例中为 MyObject)
将得到原子更新的对象的类(在本例中是 Book)
将经过原子更新的字段的名称
这里真正的价值在于,getWhatImReading 方法未经任何形式的同步便被执行,而 setWhatImReading 是作为一个原子操作执行的。
清单 4 展示如何使用 setWhatImReading() 方法并断定值的变动是正确的:
清单 4. 演习原子更新的测试用例
package com.geeckap.atomicexample;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

public class AtomicExampleTest {
	private MyObject obj;

	@Before
	public void setUp() {
		obj = new MyObject();
		obj.setWhatImReading(new Book("Java2 From Scratch"));
	}

	@Test
	public void testUpdate() {
		obj.setWhatImReading(new Book(
				"ProJavaEE 5 Performance Management and Optimization"));
		Assert.assertEquals("Incorrect book name",
				"ProJavaEE 5 Performance Management and Optimization", obj
						.getWhatImReading().getName());
	}
}
参阅参考资料了解有关原子类的更多信息。
回页首
结束语
多线程编程永远充满了挑战,但是随着Java平台的演变,它获得了简化一些多线程编程任务的支持。在本文中,我讨论了关于在Java平台上编写多线程应用程序您可能不知道的 5 件事,包括同步化方法与同步化代码块之间的不同,为每个线程存储运用
ThreadLocal 变量的价值,被广泛误解的 volatile 关键字(包括依赖于 volatile 满足同步化需求的危险),以及对原子类的错杂之处的一个简要介绍。参见
关于作者
Steven Haines 是 ioko 的一名技术架构师,也是 GeekCap Inc 的创始人。在Java编程和性能分析方面,他写过 3 本书,以及上百篇文章和十几个白皮书。Steven 还在行业会议上发表演讲,比如 JBoss World 和 STPCon,而且他曾在加里佛尼亚大学欧文分校和 Learning Tree 大学教过Java编程,他居住在佛罗里达州奥兰多市。
内容
1. 同步方法或同步代码块?
2. ThreadLocal 变量

3. Volatile 变量
4. 易失性变量与同步化
5. 原子字段更新程序
我的例子(蔡海斌):
类:

public class TestThreadLocal implements Runnable {
	int i = 0;

	// 以线程为单位的变量
	ThreadLocal threadLocal = new ThreadLocal();

	public static void main(String[] args) {
		TestThreadLocal tt = new TestThreadLocal();
		TestThreadLocal tt2 = new TestThreadLocal();
		// 下面的两个方法是通过同一个对象来进行调用的
		Thread t1 = new Thread(tt, "t1");
		Thread t2 = new Thread(tt2, "t2");// 启用这个,是多线程多实例,
		// Thread t2=new Thread(tt,"t2");//启用这个,是多线程单实例,注意全局变量 “i”的变化 和
		// threadLocal.get()的值
		t1.start();
		t2.start();
	}

	public void say() {
		String name = Thread.currentThread().getName();
		threadLocal.set(Integer.valueOf(i++));
		for (int j = 0; j < 50; j++, i++) {
			int k = Integer.valueOf(threadLocal.get().toString());
			threadLocal.set(++k);
			System.out.println(name + threadLocal.get() + "  j:" + j + " i:"
					+ i);
		}
	}

	public void run() {
		say();
	}
}
①ThreadLocal注意是线程为单位
②注意jvm的内存模型和线程的内存模型
③思考
④再思考
⑤多试多回顾。。
转发请注明出处http://blog.martoo.cn
如有漏缺,请联系我 QQ 243008827

学会”深入了解”JSP

学生时代写的,话说,我也不知道和现在有什么区别呵呵。

 

这阵子看东西的时候看到

jsp的动态导入(<jsp:include file=””>)和静态导入(<%@ include file=””%>)。。

好,我承认了,n久以前看这些的时候觉得没啥,一直跳,虽然有回顾,但始终给漏了点东西。

但是说真的,像:

 

  1. jsp的内置对象
  2. <%!   %>与<% %>的区别
  3. 再加上上面说到的那个.
其实有时候觉得钻得选方向,如果像网上经常动不动就搬一大块砖让人啃,估计过阵子牙齿掉了,顺便老年痴呆,又忘了不还得重来。
只要 知道jsp本质是个servlet,像tomcat这web容器的根目录里的work目录里能看到生成的代码就够了,没必要搞得太复杂.
像jsp的内置对象
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
        throws java.io.IOException, javax.servlet.ServletException {

    final javax.servlet.jsp.PageContext pageContext;
    javax.servlet.http.HttpSession session = null;
    final javax.servlet.ServletContext application;
    final javax.servlet.ServletConfig config;
    javax.servlet.jsp.JspWriter out = null;
    final java.lang.Object page = this;
    javax.servlet.jsp.JspWriter _jspx_out = null;
    javax.servlet.jsp.PageContext _jspx_page_context = null;

    try {
      response.setContentType("text/html;charset=ISO-8859-1");
      pageContext = _jspxFactory.getPageContext(this, request, response,
      			null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;
内置对象都摆这。变量名冲突也就这样子。编译不通过的原因都在这.
<% %>有! 跟没有的区别是做用域的问题,一个是在service方法中,一个在外面,现在回归基础就能理解有时候那些为什么exception 了
动态跟静态导入也就这样
 <%=basePath %>
 dynamic: <jsp:include page="temp.jsp"></jsp:include>
 static: <%@include file="temp.jsp" %>
 <%=basePath %>

动态导入

out.write(" dynamic: ");
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "temp.jsp", out, false);
out.write("rn");
out.write(" static: ");

静态导入有兴趣可以去看看

就是像是将两个源文件按位置合并,再转成servlet, so 变量名不能出现重复
ok,基础就到这了。知道的别拍呀!是上网查时那个火呀~~~~!
之所以纠结这些,是明白怎么运行的,比去记一堆规定要好理解,理解的东西就不容易出错。就算出错,也可以很快分析问题。Y(^_^)Y
转发请注明出处http://blog.martoo.cn
如有漏缺,请联系我 QQ 243008827

Discuz 杂记

//人老了。痛苦啊~~~东西都忘得差不多了~~!

官方操作手册:http://faq.comsenz.com/library/

一、forum

1.thread

(1).主题的显示(forum_viewthread)

$_G[‘forum_thread’] ,$post//主题的对象

$postlist[$_G[‘forum_firstpid’]]//获取当前的目标主题。因为评论也属于主题的列表。所以用这个抓取当前的主题

(2).主题的评论

discuz的大多操作是通过返回的操作进行控制的。

forum_viewthread.js:function succeedhandle_fastpost

如果有相关的操作要在执行后进行操作,可以在函数后添加操作脚本。

(3)主题分类的获取

$_G[‘forum’][‘threadtypes’][‘types’]//是个以分类id为key的数组

(4)创始人密码修改

uc_serverdataconfig.inc.php

define('UC_FOUNDERPW', '8346c0459cbc8edf1c9909c1fbc8774a');
define('UC_FOUNDERSALT', 'U25fy6');

二、门户

栏目添加自定义模板

按提示,上传文件到指定的文件夹,会自动提示。名字只要加上

<!–[name]活动列表页[/name]–>

 

dz中使用jquery

 

jq = jQuery.noConflict();//将变量$转递给jq

diy 备份转移

mysqldump -u root -p db_name pre_common_diy_data pre_common_block pre_common_block_item pre_common_template pre_common_template_block > c:db.sql

// 获取图片

$result = C::t ( 'forum_attachment' )->fetch_all_by_id ( 'tid', array (
		4530 
) );
foreach ( $result as $item ) {
	$data = C::t ( 'forum_attachment_n' )->fetch_all ( $item ['tableid'], $item ['aid'] );
	print_r ( $data );
}

// 数据抓取

$result = DB::fetch_first ( "SELECT * FROM  %t WHERE tid=%d ", array (
		'mt_video',
		4522 
) );

 

 

转发请注明出处http://blog.martoo.cn
如有漏缺,请联系我 QQ 243008827

UC 整合 PHPDISK 加检查和调试方法+补充uc socket通讯小bug

最近朋友要个网盘,因为他有个无限空间和无限流量的服务器架设论坛。

他说,迅雷和华为这些奸商都等用户有了浏量之后就开始收费了。所以流量大的草根要注意。
phpdisk的搭建也是傻瓜式的,就不多说了。
主要的配置问题,详见:

http://faq.phpdisk.com/phpdisk-connect-discuz-uc-13-view.html

注意个东西
uc_clientdatacacheapps.php
是否有你新建的app的数据,没有,复制上面的进行修改。正式机没事,但本地搭建过成中没有生成,导致通讯异常。
通讯流程见:

 

uc_clientclient.php :

function uc_user_synlogin($uid) {
	$uid = intval ( $uid );
	if (@include UC_ROOT . './data/cache/apps.php') {
		if (count ( $_CACHE ['apps'] ) > 1) { // 这里如果没有检查到,就不会去调数据哈
			$return = uc_api_post ( 'user', 'synlogin', array (
					'uid' => $uid 
			) );
		} else {
			$return = '';
		}
	}
	return $return;
}

 

关于正式机的调试和服务器的内部通讯调试.

因为在调试过程,总有不想让别人看和自己又必须得看到的数据。我就喜欢搞成这样子

if($_GET[‘test’]===’true’)//别人测试指定参数

if($_G[‘uid’]===’o’)//指定uid

这样游客就看不了啦。当然,搞完了一定要记得清楚这些小地方。

关于服务器内部通讯的调试,比如,client调server,他server怎么执行呢。

其它相关的操作。可以用 file_put_contents(time().”.txt”,var_export(array()));来记录相关的操作和信息,类似日志。这样就搞定内部通讯了。

uc通讯的一个小bug.

/uc_client/client.php:function uc_fopen

fsockopen 这个函数本身没有问题,主要问题是,uc在安装的时候,是使用公网的ip的,也就导致通讯过程中,正常是访问不了一些操作的囧~~!

像中国的sp商那些贱人一样,一出现错误页面,很喜欢给你弹到广告去。

问题来了

大家看看可爱的

/uc_client/client.php:function uc_user_synlogout

有没有,直接就把返回给返回了,竟然没有协商下过滤的。。

这样就把类似广告的东西直接当页面给加到登录和退出时的消息框里的,草根那个心急如焚呐~~~G (  ̄ ( 工 )  ̄ ) P。

坑爹啊,查到这里,哥分离脚本,一个参数一个参数的检查。。。。如此如此,这般这般。。

解决方式:

1.在uc的设置里,使用自家的独立ip。

2.在uc的设置里,取消ip,让uc访问域名(这个我没试,有兴趣的瞧瞧。代码就这么写的。出事别找我Y(^_^)Y)

if (function_exists ( 'fsockopen' )) {
	$fp = @fsockopen ( ($ip ? $ip : $host), $port, $errno, $errstr, $timeout ); // 是吧
} elseif (function_exists ( 'pfsockopen' )) {
	$fp = @pfsockopen ( ($ip ? $ip : $host), $port, $errno, $errstr, $timeout );
} else {
	$fp = false;
}

 

3.反馈bug,让uc在安装或设置的时候,检查下socket的通讯。。

注:要下载和原ucenter统一的编码,虽然pd可以指定,但是会造成通讯两边不正常的问题。如pd可同步,但是dz那边却无法同步。

解决方法:下载同编码的进行覆盖,再将system/install.lock文件进行删除,重装。

 

 

转发请注明出处http://blog.martoo.cn
如有漏缺,请联系我 QQ 243008827

php excel 导出常见问题

1.php 多功能导出工具 phpexcel

2.简单导出数据,采用table 加修改后缀的方式 ^_^

2.1 导出数据格式,解决excel格式自动化,显示异常,加样式

style=’text-align:center;vnd.ms-excel.numberformat:@’

但是注意,对于大文本,请不要加,不然会显示一堆#########

2.2导出文件头相关参数

导出相关代码,解决ie6 zip多文件异常问题

function file_down($filepath, $filename = '') {
	if (! $filename)
		$filename = basename ( $filepath );
	if ($this->is_ie ())
		$filename = rawurlencode ( $filename );
	$filetype = fileext ( $filename );
	$filesize = sprintf ( "%u", filesize ( $filepath ) );
	if (ob_get_length () !== false)
		@ob_end_clean ();
	header ( 'Pragma: public' );
	header ( 'Last-Modified: ' . gmdate ( 'D, d M Y H:i:s' ) . ' GMT' );
	header ( 'Cache-Control: no-store, no-cache, must-revalidate' );
	header ( 'Cache-Control: pre-check=0, post-check=0, max-age=0' );
	header ( 'Content-Transfer-Encoding: binary' );
	header ( 'Content-Encoding: none' );
	header ( 'Content-type: ' . $filetype );
	header ( 'Content-Disposition: attachment; filename="' . $filename . '"' );
	header ( 'Content-length: ' . $filesize );
	readfile ( $filepath );
	exit ();
}

 

2.3 iconv 转换过成中,数据丢失或没有数据输出 //IGNORE 标志,跳过异常

iconv ( 'UTF-8', 'GBK//IGNORE',$string);

 

3.导出大数据解决(其实这个是因为服务器的内存限制,导出中,字符串的拼接又过大,导致内存溢出)

$out=fopen($path,"a+");//拼接

fwite($out,$data);//一点一点输出成文件

fclose($out);

 

转发请注明出处http://blog.martoo.cn
如有漏缺,请联系我 QQ 243008827