MIT6.830 lab2 SimpleDB Operators 实验报告

一、实验概览

以下是资料对本实验的介绍

  • Implement the operators Filter and Join and verify that their corresponding tests work. The Javadoc comments for
    these operators contain details about how they should work. We have given you implementations of
    Project and OrderBy which may help you understand how other operators work.(过滤、连接)
  • Implement IntegerAggregator and StringAggregator. Here, you will write the logic that actually computes an
    aggregate over a particular field across multiple groups in a sequence of input tuples. Use integer division for
    computing the average, since SimpleDB only supports integers. StringAggegator only needs to support the COUNT
    aggregate, since the other operations do not make sense for strings.(聚合函数)
  • Implement the Aggregate operator. As with other operators, aggregates implement the OpIterator interface so that
    they can be placed in SimpleDB query plans. Note that the output of an Aggregate operator is an aggregate value of
    an entire group for each call to next(), and that the aggregate constructor takes the aggregation and grouping
    fields.
  • Implement the methods related to tuple insertion, deletion, and page eviction in BufferPool. You do not need to
    worry about transactions at this point.(插入、删除、淘汰策略)
  • Implement the Insert and Delete operators. Like all operators, Insert and Delete implement
    OpIterator, accepting a stream of tuples to insert or delete and outputting a single tuple with an integer field
    that indicates the number of tuples inserted or deleted. These operators will need to call the appropriate methods
    in BufferPool that actually modify the pages on disk. Check that the tests for inserting and deleting tuples work
    properly.

这个实验需要完成的内容有:

  1. 实现过滤、连接运算符,这些类都是继承与OpIterator接口了,该实验提供了OrderBy的操作符实现,可以参考实现。最终的SQL语句解析出来都是要依靠这些运算符的;
  2. 实现聚合函数,由于该数据库只有int和string两种类型,int类型可实现的聚合函数有max,min,avg,count等,string类型只需要实现count;这些与分组查询一起使用,选择进行聚合操作时,可以选择是否进行分组查询。
  3. 对IntegerAggregator和StringAggregator的封装,查询计划是调用Aggregate,再去调用具体的聚合器,最后获得聚合结果。
  4. 实现插入、删除记录。包括从HeapPage、HeapFile、BufferPool中删除,这里需要把三个之间的调用逻辑搞清楚,代码会好写很多。
  5. 实现BufferPool的数据页淘汰策略。BufferPool的默认数据页容量为50页,进行插入数据页的操作时,如果数据页数量大于BufferPool的容量,需要选择某中页面淘汰策略去淘汰页面,我选择的是LRU算法来淘汰页面。

二、实验过程

Exercise1:Filter and Join

exercise1要求我们完成Filter和Join两种操作符,下面是相关描述:

  • Filter: This operator only returns tuples that satisfy a Predicate that is specified as part of its constructor.
    Hence, it filters out any tuples that do not match the predicate.
  • Join: This operator joins tuples from its two children according to a JoinPredicate that is passed in as part of
    its constructor. We only require a simple nested loops join, but you may explore more interesting join
    implementations. Describe your implementation in your lab writeup.

Filter实现思路

Filter是SQL语句中where的基础,如select * from students where id > 2.Filter起到条件过滤的作用。我们进行条件过滤,使用的是迭代器FIlter的next去获取所有过滤后的记录,比如上述SQL语句的结果,相当于List<Tuple> list;即一个含有多条tuple的集合,而忽略其中的实现细节Filter就相当于list.iterator()返回的一个跌打器,我们通过it.next()去获取一条一条符合过滤条件的Tuple。

Filter是继承于Operator的,而Operator继承于抽象类OpIterator,是一个迭代器:

image-20211008162626407

由于Operator帮我们实现了next和hasNext方法,而这两个方法最终都是调用fetchNext去获取下一条记录的,所以我们在Filter要做的就是返回下一条符合过滤条件的记录;Filter的属性如下:

image-20211008164147189

其中,predicate是断言,实现条件过滤的重要属性;而child是数据源,我们从这里获取一条一条的Tuple用predicate去过滤;td是我们返回结果元组的描述信息,在Filter中与传入的数据源是相同的,而在其它运算符中是根据返回结果的情况去创建TupleDesc的;

Predicate的作用

前面我们提到:忽略其中的实现细节Filter就相当于list.iterator()返回的一个迭代器器,我们通过it.next()去获取一条一条符合过滤条件的Tuple。而其中的实现细节就是通过Predicate来实现的:

image-20211008164541094

可以看到,每次调用fetchNext,我们是从Filter的child数据源中不断取出tuple,只要有一条Tuple满足predicate的filter的过滤条件,我们就可以返回一条Tuple,即这条Tuple是经过过滤条件筛选之后的有效Tuple。

Filter是依赖于断言来实现的,即实现Filter之前需要实现Predicate,Predicate的基本属性如下:

image-20211008161434525

其中field表示的是利用传入Tuple的第几个字段来于操作数字段operand进行op运算,其中op支持的运算有:相等、大于、小于、等于、不等于、大于等于、小于等于、模糊查询这几种。

image-20211008165034972

而operand是用于参与比较的,比如上述SQL语句select * from students where id > 2;假如id是第0个字段,这里的field = 0,op = GREATER_THAN(大于),operand = new IntField(1)。这里进行比较过滤的实现在filter方法中,我们在Filter类中获取过滤后的tuple也是通过predicate.filter(tuple)方法来实现的,filter方法的实现思路如下:

image-20211008161621817

可以看到,Predicate的作用就是将传入的Tuple进行判断,而Predicate的field属性表明使用元组的第几个字段去与操作数operand进行op运算操作,比较的结果实际是调用Field类的compare方法,compare方法会根据传入的运算符和操作数进行比较,以IntField为例:

image-20211008161951068

可以看到支持的运算符有相等、大于、小于、不等于、大于等于、小于等于这些运算符,这里LIKE和EQUALS都表示等于的意思。

OrderBy的实现思路

实验提供了OrderBy的实现,其思路与我们实现的Filter也是相似的,区别在于对fetchNext的获取下一条tuple的实现有所不同。OrderBy的属性如下:

image-20211008170109175

关键的属性:

1、child:数据源,传入进行排序的所有记录Tuple;

2、childTups:OrderBy的实现思路是在open时将数据源child的所有记录存入list中,然后进行排序;

3、asc:升序还是降序,true表示升序;

4、orderByField:依据元组的第几个字段进行排序;

5、it:对childTups进行排序后childTups.iterator()返回的迭代器,原数据源child依据field字段进行排序后的所有数据。

这里的实现个人觉得不是特别好,当数据源的tuple特别多的时,可能会出现OOM(有点十亿数据进行排序那味了)。

这里主要看open的实现,因为在open中实现了排序并存入it迭代器中,后续调用fetchNext只需要在it中取就行了:

image-20211008170825549

fetchNext就简单很多了,直接从结果迭代器中取就完事了:

image-20211008170905232

Join与JoinPredicate的实现

理解了上面Filter与Predicate的关系以及OrderBy的实现思路,来做Join和JoinPredicate就会容易一点点了。

Join是连接查询实现的基本操作符,我们在MySQL中会区分内连接和外连接,我们这里只实现内连接。一条连接查询的SQL语句如下:

select a.*,b.* from a inner join b on a.id=b.id

Join的主要属性如下:

image-20211008172134954

其中child1,child2是参与连接查询的两个表的元数据,从里面取出tuple使用joinPredicate进行连接过滤。td是结果元组的描述信息,使用内连接我们是将两个表连起来,所以如果显示连接两个表的所有字段的记录,td可以简单理解成两个child数据源的两种tuple的td的拼接,这里在构造器中完成:

image-20211008172743033

实现连接查询的算法有很多种,这里实现的是最简单的嵌套循环连接(NLP),就是从数据源child1中取出一条tuple,然后不断的与child2取出的tuple进行比较,如果满足条件则拼成新的结果tuple加入结果集,不满足则继续取child2的下一条tuple,直到child2没有记录了,再从child1中取出下一条,继续从child2的第一条开始比较,如此往复,直到child1没有记录了。这个算法的时间复杂度是O(m * n)其中m是child1的记录条数,n是child2的记录条数。

具体实现代码在fetchNext中,如下:

protected Tuple fetchNext() throws TransactionAbortedException, DbException {
   
        // some code goes here
        //后面如果it1走到了后面,但是it2还有数据,可以用t1取匹配it2的数据
        TupleDesc td1 = child1.getTupleDesc(), td2 = child2.getTupleDesc();
        while (child1.hasNext() || t1 != null) {
   
            if(child1.hasNext() && t1 == null) {
   
                t1 = child1.next();
            }
            Tuple t2;
            while(child2.hasNext()) {
   
                t2 = child2.next();
                if(joinPredicate.filter(t1, t2)) {
   
                    Tuple res = new Tuple(td);
                    int i = 0;
                    for(; i < td1.numFields(); i++) {
   
                        res.setField(i, t1.getField(i));
                    }
                    for(int j = 0; j < td2.numFields(); j++) {
   
                        res.setField(i + j, t2.getField(j));
                    }
                    //如果刚好是最后一个匹配到,需要重置child2指针和设置t1=null
                    if(!child2.hasNext()) {
   
                        child2.rewind();
                        t1 = null;
                    }
                    return res;
                }
            }
            //每次child2迭代器走到终点,需要进行重置child2的指针,否则会导致死循环;t1=null是为了选取child1的下一个tuple
            child2.rewind();
            t1 = null;
        }
        return null;
    }

这里要注意的child2指针重置的时机,一个是child1匹配到的刚好是child2的最后一条记录,这时需要重置(不重置的话取出child1的下一条tuple就不是与child2的第一条tuple进行比较了);另一个时机是child1的一条tuple与child2所有tuple都不匹配,这时child1需要选取下一条tuple进行比较,child2理所应当要从第一条tuple的位置开始迭代。

上面所提到的进行比较看是否匹配,跟前面Filter一样要我们去实现JoinPredicate来实现过滤,而JoinPredicate的实现也是依托与具体Field的compare方法来实现的:

image-20211008174142916

Exercise2:Aggregates

exercise2的介绍:

An additional SimpleDB operator implements basic SQL aggregates with a
GROUP BY clause. You should implement the five SQL aggregates
(COUNT, SUM, AVG, MIN,
MAX) and support grouping. You only need to support aggregates over a single field, and grouping by a single field.

In order to calculate aggregates, we use an Aggregator(聚合器)
interface which merges a new tuple into the existing calculation of an aggregate. The Aggregator is told during
construction what operation it should use for aggregation. Subsequently, the client code should
call Aggregator.mergeTupleIntoGroup() for every tuple in the child iterator. After all tuples have been merged, the
client can retrieve a OpIterator of aggregation results. Each tuple in the result is a pair of the
form (groupValue, aggregateValue), unless the value of the group by field was Aggregator.NO_GROUPING, in which case
the result is a single tuple of the form (aggregateValue).

Note that this implementation requires space linear in the number of distinct groups. For the purposes of this lab, you
do not need to worry about the situation where the number of groups exceeds available memory.

exerciese2要求我们实现各种聚合运算如count、sum、avg、min、max等,并且聚合器需要拥有分组聚合的功能。如以下SQL语句:

SELECT SUM(fee) AS country_group_total_fee, country FROM member GROUP BY country

这条语句的功能是查询每个国家的费用总和及国家名称(根据国家名称进行分组),这里用到了聚合函数SUM。其中fee是聚合字段,country是分组字段,这两个字段是我们理解聚合运算的关键点。

You only need to support aggregates over a single field, and grouping by a single field.讲义告诉我们,我们只需实现根据一个字段去分组和聚合,也就是只有一个分组字段和一个聚合字段。

exercise2的实验要求:

Implement the skeleton methods in:


  • src/java/simpledb/execution/IntegerAggregator.java
  • src/java/simpledb/execution/StringAggregator.java
  • src/java/simpledb/execution/Aggregate.java

At this point, your code should pass the unit tests IntegerAggregatorTest, StringAggregatorTest, and AggregateTest.
Furthermore, you should be able to pass the AggregateTest system test.

IntegerAggregator的实现

IntegerAggregator的本质是一个迭代器,用于对指定的字段进行聚合,下面是基本属性:

    private int groupField;
    private Type groupFieldType;
    private int aggregateField;
    private Op aggregateOp;

    private TupleDesc td;

    /**
     * 计算int类型字段的聚合值,可以实现MIN、MAX、COUNT、SUM
     */
    private Map<Field, Integer> groupMap;
    /**
     * AVG比较特殊,需要先加到list中,最后再算平均值,保证准确性
     */
    private Map<Field, List<Integer>> avgMap;

其中,groupField是指依据tuple的第几个字段进行分组,当无需分组时groupField的值为-1,在上面的SQL语句中相当于country这个字段;groupFieldType是分组字段的类型,如果无需分组这个属性值为null;aggregateField是指对tuple的第几个字段进行聚合,在上面的SQL语句中相当于fee字段;aggregateOp是进行聚合运算的操作符,相当于上述SQL语句的SUM。td是结果元组的描述信息,对于有分组的聚合运算,td是一个拥有两个字段的TupleDesc,以(groupField, aggregateField)的形式,保存原tuple进行分组聚合后每个分组对应的聚合结果,对于没有分组的聚合运算,td只有一个字段来保存聚合结果;而groupMap、avgMap用于保存聚合的结果集,后面进行运算会用到。

下面是构造器,主要是根据传入的参数对以上的属性进行初始化,其中NO_GROUPING是常数-1

public IntegerAggregator(int gbfield, Type gbfieldtype, int afield, Op what) {
   
        // some code goes here
        this.groupField = gbfield;
        this.groupFieldType = gbfieldtype;
        this.aggregateField = afield;
        this.aggregateOp = what;
        groupMap = new HashMap<>();
        avgMap = new HashMap<>();
        this.td = gbfield != NO_GROUPING ?
                new TupleDesc(new Type[]{
   gbfieldtype, Type.INT_TYPE}, new String[]{
   "gbVal", "aggVal"})
                : new TupleDesc(new Type[]{
   Type.INT_TYPE}, new String[]{
   "aggVal"});
    }

不管是IntegerAggregator还是StringAggregator,他们的作用都是进行聚合运算(分组可选),所以他们的核心方法在于mergeTupleIntoGroup。IntegerAggregator.mergeTupleIntoGroup(Tuple tup)的实现思路是这样的:

1.根据构造器给定的aggregateField获取在tup中的聚合字段及其值;

2.根据构造器给定的groupField获取tup中的分组字段,如果无需分组,则为null;这里需要检查获取的分组类型是否正确;

3.根据构造器给定的aggregateOp进行分组聚合运算,对于MIN,MAX,COUNT,SUM,我们将结果保存在groupMap中,key是分组字段(如果无需分组则为null),val是聚合结果;对于AVG,我们不能直接进行运算,因为整数的除法是不精确的,我们需要把所以字段值用个list保存起来,当需要获取聚合结果时,再进行计算返回。

下面是具体代码:

    public void mergeTupleIntoGroup(Tuple tup) {
   
        // some code goes here
        //获取聚合字段
        IntField aField = (IntField) tup.getField(aggregateField);
        //获取聚合字段的值
        int value = aField.getValue();
        //获取分组字段,如果单纯只是聚合,则该字段为null
        Field gbField = groupField == NO_GROUPING ? null : tup.getField(groupField);
        if (gbField != null && gbField.getType() != this.groupFieldType && groupFieldType != null) {
   
            throw new IllegalArgumentException("Tuple has wrong type");
        }
        //根据聚合运算符处理数据
        switch (aggregateOp) {
   
            case MIN:
                groupMap.put<
  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Appendix CWriting Your Own Functions. . . . . . . . . . . . . . . . . . 487 The Structure of Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 488 Returning Values from Functions. . . . . . . . . . . . . . . . . . . . . . . 488 Using Functions in Your Code. . . . . . . . . . . . . . . . . . . . . . . . . . . . 491 Using include() and require(). . . . . . . . . . . . . . . . . . . . . . . . . . . 492 Appendix DWriting Your Own Classes and Objects. . . . . . . . . . 495 Working with Objects. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 496 Creating an Object. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 497 Object Inheritance. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 501 Namespaces. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 502 Appendix EDatabase Normalization and SQL Reference. . . . . . 505 Understanding Database Normalization. . . . . . . . . . . . . . . . . . . . 506 Applying the Normal Forms. . . . . . . . . . . . . . . . . . . . . . . . . . . 506 Normalizing the my_contacts Table. . . . . . . . . . . . . . . . . . . . . 510 Other Normal Forms. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 513 Basic MySQL Reference. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 513 Creating or Dropping a Database. . . . . . . . . . . . . . . . . . . . . . 514 Creating or Dropping a Table. . . . . . . . . . . . . . . . . . . . . . . . . . 514 Altering a Table. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515 Inserting, Updating, or Replacing Within a Table. . . . . . . . . . . 515 Deleting from a Table. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 517 Selecting from a Table. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 517 Grouping, Ordering, and Selecting Unique Values. . . . . . . . . 520 Using the SHOW Command. . . . . . . . . . . . . . . . . . . . . . . . . . . 521 Appendix FUsing SQLite. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 523 Examples of SQLite in Action. . . . . . . . . . . . . . . . . . . . . . . . . . . . 524 Creating a Table and Storing Data with SQLite. . . . . . . . . . . . 525 Retrieving Items with SQLite. . . . . . . . . . . . . . . . . . . . . . . . . . 526 Performing Other Tasks with SQLite. . . . . . . . . . . . . . . . . . . . 528 xvii CONTENTS Appendix GGetting Help. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 535 PHP Resources. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 536 Web Sites. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 536 Mailing Lists. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538 User Groups. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538 MySQL Resources. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538 Apache Resources. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 539 Index. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 541 Introduction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix PART I GETTING STARTED. . . . . . . . . . . . . . . . . . . . . . . . . . 1 Chapter 1 Installing and Configuring MySQL. . . . . . . . . . . . . . . . 3 Various MySQL Distributions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 Installing MySQL on Windows. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 Testing Your MySQL Installation. . . . . . . . . . . . . . . . . . . . . . . . . 12 Installing MySQL for Linux. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 Testing Your MySQL Installation. . . . . . . . . . . . . . . . . . . . . . . . . 20 Chapter 2 Installing Apache. . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 Installing Apache for Windows. . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 Configuring Apache on Windows. . . . . . . . . . . . . . . . . . . . . . . . 29 Starting and Connecting to Apache. . . . . . . . . . . . . . . . . . . . . . 31 Installing Apache for Linux/UNIX. . . . . . . . . . . . . . . . . . . . . . . . . . 32 Configuring Apache on Linux/UNIX. . . . . . . . . . . . . . . . . . . . . . 34 Starting and Connecting to Apache. . . . . . . . . . . . . . . . . . . . . . 36 Chapter 3 Installing PHP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 Installing PHP for Windows. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 Configuring Apache to Use PHP. . . . . . . . . . . . . . . . . . . . . . . . . 41 Testing the PHP Installation. . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 Installing PHP for Linux/UNIX. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 Configuring Apache to Use PHP. . . . . . . . . . . . . . . . . . . . . . . . . 46 Testing the PHP Installation. . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 PART II THE ABSOLUTE BASICS OF CODING IN PHP. . . . 49 Chapter 4 Mixing PHP and HTML. . . . . . . . . . . . . . . . . . . . . . . . 51 How PHP Is Parsed. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 PHP Start and End Tags. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 Code Cohabitation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 The Importance of the Instruction Terminator. . . . . . . . . . . . . . 57 Escaping Your Code. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 Commenting Your Code. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 Chapter 5 Introducing Variables and Operators. . . . . . . . . . . . 65 What’s a Variable?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 Naming Your Variables. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 PHP Variable and Value Types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 What’s an Operator?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 Assignment Operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 Arithmetic Operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 Comparison Operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 Logical Operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 viii CONTENTS Chapter 6 Using PHP Variables. . . . . . . . . . . . . . . . . . . . . . . . . 85 Getting Variables from Forms. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 Creating a Calculation Form. . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 Creating the Calculation Script. . . . . . . . . . . . . . . . . . . . . . . . . . 89 Submitting Your Form and Getting Results. . . . . . . . . . . . . . . . 91 HTTP Environment Variables. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 Retrieving and Using REMOTE_ADDR. . . . . . . . . . . . . . . . . . . . 93 Retrieving and Using HTTP_USER_AGENT. . . . . . . . . . . . . . . . 95 PART III START WITH THE SIMPLE STUFF. . . . . . . . . . . . . . 97 Chapter 7 Displaying Dynamic Content. . . . . . . . . . . . . . . . . . . 99 Displaying Browser-Specific HTML. . . . . . . . . . . . . . . . . . . . . . . . 100 Displaying Platform-Specific HTML. . . . . . . . . . . . . . . . . . . . . . . . 103 Working with String Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . 107 Creating an Input Form. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 Creating a Script to Display Form Values. . . . . . . . . . . . . . . . . 109 Submitting Your Form and Getting Results. . . . . . . . . . . . . . . 111 Redirecting to a New Location. . . . . . . . . . . . . . . . . . . . . . . . . . . 113 Creating a Redirection Form. . . . . . . . . . . . . . . . . . . . . . . . . . . 113 Creating the Redirection Script and Testing It. . . . . . . . . . . . . 115 Chapter 8 Sending E-Mail. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 Using an SMTP Server. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 SMTP-Related Changes in php.ini. . . . . . . . . . . . . . . . . . . . . . 119 A Simple Feedback Form. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120 Creating the Feedback Form. . . . . . . . . . . . . . . . . . . . . . . . . . 120 Creating a Script to Mail Your Form. . . . . . . . . . . . . . . . . . . . . 122 Submitting Your Form and Getting Results. . . . . . . . . . . . . . . 125 ix CONTENTS A Feedback Form with Custom Error Messages. . . . . . . . . . . . . 127 Creating the Initial Script. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 Adding Error Checking to the Script. . . . . . . . . . . . . . . . . . . . 129 Submitting Your Form and Getting Results. . . . . . . . . . . . . . . 134 Saving the Values if You Make an Error. . . . . . . . . . . . . . . . . . 136 Chapter 9 Using Your File System. . . . . . . . . . . . . . . . . . . . . . 139 File Paths and Permissions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140 Displaying Directory Contents. . . . . . . . . . . . . . . . . . . . . . . . . . . 140 Working with fopen() and fclose(). . . . . . . . . . . . . . . . . . . . . . . . . 143 Creating a New File. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144 Appending Data to a File. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 Reading Data from a File. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 Sending File Contents via E-Mail. . . . . . . . . . . . . . . . . . . . . . . 155 File System Housekeeping. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 Copying Files. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 Renaming Files. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160 Deleting Files. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162 Chapter 10Uploading Files to Your Web Site. . . . . . . . . . . . . . 165 Checking Your php.ini File. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166 Understanding the Process. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 Creating the Form. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 Creating the Upload Script. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170 Uploading a File Using Your Form and Script. . . . . . . . . . . . . . . . 172 x CONTENTS PART IV GETTING TO KNOW YOUR MYSQL DATABASE. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 Chapter 11Establishing a Connection and Poking Around. . . . 177 Working with User Privileges in MySQL. . . . . . . . . . . . . . . . . . . . 178 Creating a New User. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178 Connecting to MySQL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 Breaking Your Connection Script. . . . . . . . . . . . . . . . . . . . . . . 182 Listing Databases on a Server. . . . . . . . . . . . . . . . . . . . . . . . . . . . 183 Listing Tables in a Database. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187 Creating a New Database. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191 Deleting a Database. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194 Chapter 12Creating a Database Table. . . . . . . . . . . . . . . . . . . . 197 Planning for Your Tables. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198 Basic MySQL Data Types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198 Defining Your Fields. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198 The Importance of Unique Fields. . . . . . . . . . . . . . . . . . . . . . . 201 A Two-Step Form Sequence. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202 Step 1: Number of Fields. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202 Step 2: Defining Your Fields. . . . . . . . . . . . . . . . . . . . . . . . . . . 203 Starting the Table Creation Process. . . . . . . . . . . . . . . . . . . . . 208 Creating the Table-Creation Script. . . . . . . . . . . . . . . . . . . . . . . . 210 Create That Table!. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214 Chapter 13Inserting Data into the Table. . . . . . . . . . . . . . . . . . 217 Creating the Record Addition Form. . . . . . . . . . . . . . . . . . . . . . . 218 Creating the Record Addition Script. . . . . . . . . . . . . . . . . . . . . . . 222 Populating Your Table. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228 xi CONTENTS Chapter 14Selecting and Displaying Data. . . . . . . . . . . . . . . . . 231 Planning and Creating Your Administrative Menu. . . . . . . . . . . . 232 Selecting Data from the my_music Table. . . . . . . . . . . . . . . . . . . 233 Displaying Records Ordered by ID. . . . . . . . . . . . . . . . . . . . . . 234 Displaying Records Ordered by Date Acquired. . . . . . . . . . . . 237 Displaying Records Ordered by Title. . . . . . . . . . . . . . . . . . . . 238 Displaying Records Ordered by Artist. . . . . . . . . . . . . . . . . . . 240 Displaying Records Ordered by Multiple Criteria. . . . . . . . . . 243 PART V USER AUTHENTICATION AND TRACKING. . . . . 245 Chapter 15Database-Driven User Authentication. . . . . . . . . . . 247 Why Authenticate Anyone?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248 Creating the User Table. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248 Adding Users to Your Table. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249 Creating the User Addition Form and Script. . . . . . . . . . . . . . 250 Adding Some Users. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255 Creating the Login Form. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257 Creating the Authentication Script. . . . . . . . . . . . . . . . . . . . . . . . 258 Trying to Authenticate Yourself. . . . . . . . . . . . . . . . . . . . . . . . . . . 261 Chapter 16Using Cookies. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263 What Are Cookies?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264 Setting Cookies. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264 Counting Time. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266 Setting a Test Cookie. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266 Using Cookie Variables. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269 Using Cookies with Authentication. . . . . . . . . . . . . . . . . . . . . 269 xii CONTENTS Chapter 17Session Basics. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277 Before You Begin…Checking php.ini. . . . . . . . . . . . . . . . . . . . . . 278 What’s a Session?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278 Understanding Session Variables. . . . . . . . . . . . . . . . . . . . . . . . . 279 Starting a Session. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280 Registering and Modifying Session Variables. . . . . . . . . . . . . . 282 Managing User Preferences with Sessions. . . . . . . . . . . . . . . . . . 284 Starting a Session and Registering Defaults. . . . . . . . . . . . . . . 284 Making Preference Changes. . . . . . . . . . . . . . . . . . . . . . . . . . . 288 Displaying Changes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292 PART VI CREATING YOUR OWN CONTACT MANAGEMENT SYSTEM. . . . . . . . . . . . . . . . . . . 293 Chapter 18Planning Your System. . . . . . . . . . . . . . . . . . . . . . . 295 Planning and Creating the Administration Menu. . . . . . . . . . . . . 296 Logging In to the Administration Menu. . . . . . . . . . . . . . . . . . 301 Defining the my_contacts Table. . . . . . . . . . . . . . . . . . . . . . . . . . 303 Modifying the Table-Creation Scripts. . . . . . . . . . . . . . . . . . . . 304 Creating the my_contacts Table. . . . . . . . . . . . . . . . . . . . . . . . 309 Chapter 19Adding Contacts. . . . . . . . . . . . . . . . . . . . . . . . . . . 313 Creating the Record-Addition Form. . . . . . . . . . . . . . . . . . . . . . . 314 Creating the Record-Addition Script. . . . . . . . . . . . . . . . . . . . . . 319 Populating Your Table. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324 Chapter 20Modifying Contacts. . . . . . . . . . . . . . . . . . . . . . . . . 327 Creating the Record-Selection Form. . . . . . . . . . . . . . . . . . . . . . 328 Creating the Record-Modification Form. . . . . . . . . . . . . . . . . . . . 333 Creating the Record-Modification Script. . . . . . . . . . . . . . . . . . . 338 Modifying Contacts. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342 xiii CONTENTS Chapter 21Deleting Contacts. . . . . . . . . . . . . . . . . . . . . . . . . . 345 Using the Record-Selection Form. . . . . . . . . . . . . . . . . . . . . . . . . 346 Creating the Record-Deletion Form. . . . . . . . . . . . . . . . . . . . . . . 351 Creating the Record-Deletion Script. . . . . . . . . . . . . . . . . . . . . . . 355 Deleting Contacts. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358 Chapter 22Working with Contacts. . . . . . . . . . . . . . . . . . . . . . 361 Modifying Your Administrative Menu. . . . . . . . . . . . . . . . . . . . . . 362 Showing the Number of Contacts. . . . . . . . . . . . . . . . . . . . . . 362 Displaying Today’s Date. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370 Showing the Birthdays in the Current Month. . . . . . . . . . . . . . 372 Selecting Data from the my_contacts Table. . . . . . . . . . . . . . . . . 379 Displaying the Record List. . . . . . . . . . . . . . . . . . . . . . . . . . . . 379 Displaying Read-Only Records. . . . . . . . . . . . . . . . . . . . . . . . . 383 PART VII ADDITIONAL PROJECT EXAMPLES. . . . . . . . . . . 391 Chapter 23Managing a Simple Mailing List. . . . . . . . . . . . . . . . 393 A Brief Word About Mailing List Software. . . . . . . . . . . . . . . . . . 394 Developing a Subscription Mechanism. . . . . . . . . . . . . . . . . . . . . 394 Creating the subscribers Table. . . . . . . . . . . . . . . . . . . . . . . . . 394 Creating the Subscription Form. . . . . . . . . . . . . . . . . . . . . . . . 396 Testing the Subscription Form. . . . . . . . . . . . . . . . . . . . . . . . . 403 Developing the Mailing Mechanism. . . . . . . . . . . . . . . . . . . . . . . 406 Creating the Newsletter Form. . . . . . . . . . . . . . . . . . . . . . . . . 406 Creating the Script to Mail Your Newsletter. . . . . . . . . . . . . . 407 Testing Your Mailing List Mechanism. . . . . . . . . . . . . . . . . . . . 410 Troubleshooting Your Mailing List Mechanism. . . . . . . . . . . . . 411 xiv CONTENTS Chapter 24Creating Custom Logs and Reports. . . . . . . . . . . . . 413 A Note About Apache Log Files. . . . . . . . . . . . . . . . . . . . . . . . . . 414 Simple Access Counting with MySQL. . . . . . . . . . . . . . . . . . . . . . 415 Creating the Database Table. . . . . . . . . . . . . . . . . . . . . . . . . . 415 Creating the Code Snippet. . . . . . . . . . . . . . . . . . . . . . . . . . . . 416 Displaying the Count. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420 Creating Your Personal Access Report. . . . . . . . . . . . . . . . . . . 422 Chapter 25Working with XML. . . . . . . . . . . . . . . . . . . . . . . . . . 433 What Is XML?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 434 Basic XML Document Structure. . . . . . . . . . . . . . . . . . . . . . . . 434 Preparing to Use XML with PHP. . . . . . . . . . . . . . . . . . . . . . . . . . 437 Parsing XML with PHP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 438 Parse and Display Content from XML Files. . . . . . . . . . . . . . . 439 PART VIII APPENDIXES. . . . . . . . . . . . . . . . . . . . . . . . . . . . 443 Appendix AAdditional Configuration Options. . . . . . . . . . . . . . 445 Windows Extensions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 446 Linux Configuration Options. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448 Appendix BBasic PHP Language Reference. . . . . . . . . . . . . . . . 451 PHP Start and End Tags. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452 Variables. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452 Floats. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453 Integers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453 Strings. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453 Variables from HTML Forms. . . . . . . . . . . . . . . . . . . . . . . . . . . 454 Variables from Cookies. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 454 Environment Variables. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 454 Arrays. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 455 xv CONTENTS Operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 456 Arithmetic Operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 456 Assignment Operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 456 Comparison Operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 456 Increment/Decrement Operators. . . . . . . . . . . . . . . . . . . . . . . 457 Logical Operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 457 Control Structures. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 458 if...else if...else. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 459 while. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 460 for. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 460 foreach. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 461 Built-In Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 461 Array Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 461 Database Connectivity Functions for MySQL. . . . . . . . . . . . . . 465 Date and Time Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 466 File System Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 468 HTTP Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 472 mail() Function. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 473 Mathematical Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474 Miscellaneous Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 476 Program Execution Functions. . . . . . . . . . . . . . . . . . . . . . . . . . 478 Regular Expression Functions. . . . . . . . . . . . . . . . . . . . . . . . . . 479 Session-Handling Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . 480 String Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 481 Variable Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 485 Other Changes for PHP 6.0. . . . . . . . . . . . . . . . . . . . . . . . . . . 486 xvi CONTENTS

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值