duanjia7607 2009-09-09 18:22
浏览 80
已采纳

获取OOP PHP日历应用程序一次更新两个表

I'm building a PHP calendar app for a photography group. They need to be able to assign multiple dates/times to a single event.

As of now, I have an Events table and a Slots table (for time slots). Events only has id, title, and description, while Slots has id, start time, end time, and event_id as a foreign key.

I've created an Event class and a Slot class, and have a form for updating events that should be able to update both tables on submit by triggering an $event->save() method, and then cycling through each of the slots and triggering a $slot->save() method for each.

I've included the code below. When I submit the form, I'm getting back an error on the $slot->save() section, and I can't figure out why.

UPDATE: Adding code for some methods.

        public static function find_by_id($id=0) {
            global $database;
            $result_array = self::find_by_sql("SELECT * FROM " . self::$table_name . " WHERE id={$id} LIMIT 1 ");
            return !empty($result_array) ? array_shift($result_array) : false;
        }

        public static function find_by_sql($sql="") {
            global $database;
            $result_set = $database->query($sql);
            $object_array = array();
            while ($row = $database->fetch_array($result_set)) {
                $object_array[] = self::instantiate($row);
            }
            return $object_array;
        }

        private static function instantiate($record) {
            // Could check that $record exists and is an array
            // Simple, long-form approach: (if 100 cols, this would be huge)
            // PHP 5.3 LSB : $class_name = get_called_class();
            $object = new self;
            // $object->id      = $record['id'];
            // $object->username    = $record['username'];
            // $object->password    = $record['password'];
            // $object->first_name = $record['first_name'];
            // $object->last_name   = $record['last_name'];

            // More dynamic, short-form approach:
            foreach($record as $attribute=>$value) {
                if($object->has_attribute($attribute)) {
                    $object->$attribute = $value;
                }
            }       
            return $object;
        }

        public function save() {
            // A new record won't have an id yet.
            return isset($this->id) ? $this->update() : $this->create();
        }

        protected function create() { // protected so you are forced to call save() method for safety (no duplicate creates)
            global $database;
            $attributes = $this->sanitized_attributes();
            $sql = "INSERT INTO ". self::$table_name ." (";
            $sql .= join(", ", array_keys($attributes));
            $sql .= ") VALUES ('";
            $sql .= join("', '", array_values($attributes));
            $sql .= "')";
            if($database->query($sql)) {
                $this->id = $database->insert_id();
                return true;
            } else {
                return false;
            }
        }

        protected function update() {
            global $database;
            $attributes = $this->sanitized_attributes();
            $attribute_pairs = array();
            foreach ($attributes as $key => $value) {
                $attribute_pairs[] = "{$key} = '{$value}'";
            }
            $sql = "UPDATE ". self::$table_name ." SET ";
            $sql .= join(", ", $attribute_pairs);
            $sql .= " WHERE id=". $database->escape_value($this->id);
            $database->query($sql);
            return ($database->affected_rows() == 1) ? true : false;

        }           

And now onto the original code:

<?php
require_once('../../includes/init.php');
if (!$session->is_logged_in()) { redirect_to("login.php"); }
$user = User::find_by_id($session->user_id);

if (!isset($_GET['e'])) { redirect_to("calendar.php"); }
else { $event_id = $_GET['e']; }

$sql = "SELECT * FROM slots WHERE event_id = {$event_id}";

// find_by_sql() method also instantiates each row as a new Slot object
// $slots is now an array() of objects
$slots = Slot::find_by_sql($sql);

// new Slot object used for adding a time slot to current event
$blank_slot = new Slot();

// initialize $message var to ""
$message="";

// Check to see if either of the submit buttons have been set in the $_POST
if (isset($_POST['edit_event']) || isset($_POST['add_slot'])) {

// Counts the number of slots associated with the current event id
// Add one so that there is a blank field to add another time slot
$count = count($slots) + 1;

// Vars for checking if the last m/d/y is set in the form, before adding another slot field
$check_month = "month" . $count;
$check_year = "year" . $count;
$check_day = "day" . $count;

// initialize running errors var
$errors = 0;

// Don't add another slot field if the previous one has not been set
if (isset($_POST['add_slot']) && (empty($_POST[$check_month]) || empty($_POST[$check_year]) || empty($_POST[$check_day]))) {
                $message .= "Oops, you must enter a value for all months, dates, and years before adding a new date to this event.<br />";
                $errors++;

} else {
    // create new Event object and set attrs from $_POST vars   
    $event = new Event();       
    $event->id = $event_id;
    $event->title = $_POST['title'];
    $event->description = $_POST['description'];
    $event->category = $_POST['cat'];

    $new_event = $event->save();
    if ($new_event = true) {
        $i = 1;
        // for each of the $slots objects...
        foreach ($slots as $slot) {
            // get the db_fields for the object
            $fields = Slot::get_db_fields();
            // for each field...
            foreach ($fields as $field) {
                // create a $field_n var that appends $i, to match $_POST name
                $field_n = $field . $i;
                if ($field == 'id') {
                    $slot_id_n = "slot_id" . $i;
                    $slot->id = $_POST[$slot_id_n];
                }
                elseif ($field == 'start_hour') {
                    $start_ampm_n = "start_ampm" . $i;
                    $start_hour = Slot::convert_to_military($_POST[$field_n], $_POST[$start_ampm_n]);
                    $slot->start_hour = $start_hour;
                } elseif ($field == 'end_hour') {
                    $end_ampm_n = "end_ampm" . $i;
                    $end_hour = Slot::convert_to_military($_POST[$field_n], $_POST[$end_ampm_n]);
                    $slot->end_hour = $end_hour;
                } elseif ($field == 'start_ampm' || $field == 'end_ampm') {
                } elseif ($field == 'event_id') {
                    $slot->event_id = $event_id;
                } elseif ($field == 'status') {
                    $slot->status = "confirmed";
                } else {
                    $slot->$field = $_POST[$field_n];
                }
            }

            // save() method runs create() or update() method
            $save_slot = $slot->save();
            // save m and y for redirecting back to calendar
            $last_month = $slot->month;
            $last_year = $slot->year;
            if ($save_slot == false) {

 // THIS IS THE ERROR I AM ALWAYS GETTING

                $message .= "(1) Problem saving time slot number {$i}.<br />"; 
                // rollback previous $slot and $event saves!
                $errors++;
            }

        $i++;
        }
        // add the new time slot, if it exists
        if (!empty($_POST[$check_month]) && !empty($_POST[$check_year]) && !empty($_POST[$check_day])) {
            $fields = Slot::get_db_fields();
            foreach ($fields as $field) {
                $field_n = $field . $i;
                if ($field == 'id') {
                $slot_id_n = "slot_id" . $i;
                    if(!empty($_POST[$slot_id_n])) {
                        $blank_slot->id = $_POST[$slot_id_n];
                    } else {
                        $blank_slot->id = NULL;
                    }
                }
                elseif ($field == 'start_hour') {
                    $start_ampm_n = "start_ampm" . $i;
                    $start_hour = Slot::convert_to_military($_POST[$field_n], $_POST[$start_ampm_n]);
                    $blank_slot->start_hour = $start_hour;
                } elseif ($field == 'end_hour') {
                    $end_ampm_n = "end_ampm" . $i;
                    $end_hour = Slot::convert_to_military($_POST[$field_n], $_POST[$end_ampm_n]);
                    $blank_slot->end_hour = $end_hour;
                } elseif ($field == 'start_ampm' || $field == 'end_ampm') {
                } elseif ($field == 'event_id') {
                    $blank_slot->event_id = $event_id;
                } elseif ($field == 'status') {
                    $blank_slot->status = "confirmed";
                } else {
                    $blank_slot->$field = $_POST[$field_n];
                }
            }
            $save_slot = $blank_slot->save();
            $last_month = $blank_slot->month;
            $last_year = $blank_slot->year;
            if ($save_slot == false) {
                $message .= "Problem saving time slotb number {$i}.<br />";
                // rollback previous $slot and $event saves!
                $errors++;
            }
        }       
    } else {
        $message .= "Error updating the event.<br />";
        $errors++;
    }

    if ($errors == 0) {
        $redirect = "calendar.php";
        if (isset($last_month) && isset($last_year)) {
            $redirect .= "?m={$last_month}&y={$last_year}";
        }
        if (isset($_POST['edit_event'])) { redirect_to($redirect); }
    }
}
}
$event = Event::find_by_id($event_id);
?>

<?php include_layout_template('header.php'); ?>
<div id="main"> 
    <h1>Edit Event</h1>
    <?php if (!empty($message)) { echo "<p class='message'>" . $message . "</p>"; } ?>
    <a href="calendar.php">Cancel (Go back to the Calendar)</a></p><br /><br />
    <form style="width: 700px;" action="?e=<?php echo $event_id; ?>" method="post">
    <?php echo $event->build_event_form(); ?>
    <?php 
    $sql = "SELECT * FROM slots WHERE event_id = {$event_id}";
    $slots = Slot::find_by_sql($sql);
    ?>
<br /><br />
<?php
    $num = 1;
    foreach ($slots as $slot) {
        echo $slot->build_slot_form($num);
        $num++;
    }
    echo $blank_slot->build_slot_form($num);
?>
    <br /><br /><br />
    <input type="hidden" name="date_count" value="<?php echo $num; ?>">
    <input type="submit" name="edit_event" value="Edit Event" />
    <input type="submit" name="add_slot" value="Add Another Date">
    </form>

</div>

<?php include_layout_template('footer.php'); ?>
  • 写回答

2条回答 默认 最新

  • dqbh8054 2009-09-11 02:03
    关注

    The answer arises! My update() method (called by the save() method) used mysql_affected_rows() to verify if the update occurred. My form includes multiple possible updates. Each update, 1, all, or none of them could be updated (if the Event details were updated, you could update none of the time slots below).

    As soon as my code arrived at a time slot that wasn't actually being changed, mysql_affected_rows() returned 0. On UPDATE, that's how mysql_affected_rows() works.

    So the evaluation returned false even though everything worked. I switched the update() method from "if (mysql_affected_rows == 1)" to instead say "if (mysql_affected_rows !== -1)" which will verify that no mysql error occurred, even if 0 rows were affected.

    Thanks anyway!

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料