Thread Meldeliste auf Website erstellen (23 answers)
Opened by seemann at 2011-07-14 18:45

rosti
 2011-07-15 13:31
#150440 #150440
User since
2011-03-19
3206 Artikel
BenutzerIn
[Homepage]
user image
hi, ich habe mal eine kleine Klasse vorbereitet, womit Du den DB-Kram von Deinem CGI-Script trennen kannst. Es ist noch nicht ganz optimal, aber ein guter Anfang. Speichere untenstehende Datei als 'Base.pm' im /cgi-bin/, also im gleichen Verzeichnis wie das CGI-Script.

Mit dem Objekt kannst Du die Tabelle erstellen (Felder anpassen), die Tabelle löschen und Werte einfügen.

Spiel mal ein bischen mit dem Modul.

Edit: Wenn Dir das Prinzip == 'DB-Zugriff über eine Klasse' zusagt, mein Vorschlag:

Ich schreibe Dir das Modul für den DB-Zugriff (mit Feldern entsprechend Deines Formulars), es wird kleiner als untenstehend und ist leicht anzuwenden. Das Drumherum, HTML, CGI-Script ist dann nur noch Tipparbeit Deinerseits.

Das Modul wird den Namen 'Kladde' bekommen, die Ableitungen ::DBI und ::CGI nehme ich raus.


Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# Dateiname: Base.pm


# general pragmas
use strict;
use warnings;

package Base;

# Main-Object der Superklasse
sub new{
        my $class = shift;
        # Definiere die erforderlichen Felder
        # [0]-> Attribute DB
        my $self = bless{
                FIELDS => {
                        name =>  ["varchar(100) NOT NULL DEFAULT ''"],
                        vname => ["varchar(100) NOT NULL DEFAULT ''"],
                        type =>  ["varchar(100) NOT NULL DEFAULT ''"],
                        descr => ["text"],
                },
                DBH => undef,
                CGI => undef,
        }, $class;
        return $self;
}
1;#########################################################################

package Base::DBI::CGI;

# Bestimmung: 
# Object und Methoden für Zugriff auf Datenbank (wird geerbt)
# Darstellung HTML-Formular
# Formularverarbeitung, delegierung param()-method, header()-method

use CGI;
use base qw(Base::DBI);

# Inherit from Base::DBI
sub new{
        my $param = shift;
        my $class = ref($param) || $param;
        my $self = $class->SUPER::new(@_);
        # add the CGI-Attribute, perform the param-method
        $self->{CGI} = CGI->new;
        return $self;
}

############################ PUBLIC METHODS ###############################
# delegiere CGI::param
sub param{
        my $self = shift;
        return $self->{CGI}->param(@_);
}
# delegiere CG::header Method
sub header{
        my $self = shift;
        return $self->{CGI}->header(@_);
}
1;#########################################################################

package Base::DBI;

# Bestimmung: Zugriff auf die Datenbank

use DBI;
use base qw(Base);
use Carp;


# Inherit from 'Base'
sub new{
        my $param = shift;
        my $class = ref($param) || $param;
        my $self = $class->SUPER::new;
        # add the DatabaseHandle
        $self->_handle(@_) or croak "Keine Verbindung zur DB: $@";
        return $self;
}

########################## PRIVATE METHODS ################################
sub _handle{
        my $self = shift;
        # Default Settings
        my %opts = (
                base => undef,         # Name der Datenbank
                user => '',
                pass => '',
                port => 3306,
                host => 'localhost',
                tabn => undef,         # Name der Tabelle
                @_,                    # Parameter
        );
        $self->{TABN} = $opts{tabn} or croak "No Tablename specified";
        my $dsn = "DBI:mysql:database=$opts{base};host=$opts{host};port=$opts{port}";
        eval{
                $self->{DBH} = DBI->connect_cached(
                        $dsn, $opts{user}, $opts{pass}, {
                                RaiseError => 1, 
                                PrintError => 0,
                        }
                );
                # sicherheitshalber quote Tabellenname
                $self->{TABN} = $self->{DBH}->quote_identifier($self->{TABN});
        };
        return $@ ? undef : 1;
}
######## Base::DBI ####### PUBLIC METHODS #################################
# Tabelle erstellen
sub create_table{
        my $self = shift;

        # Felder aufarbeiten, quote_identyfier
        my @fields  = ();
        foreach my $f(keys %{$self->{FIELDS}}){
                my $qf = $self->{DBH}->quote_identifier($f);
                # Attribute hinzu
                push @fields, qq($qf $self->{FIELDS}->{$f}->[0]);
        }
        my $fields = join ",", @fields;

        # Statement
        my $q = qq(
                CREATE TABLE IF NOT EXISTS $self->{TABN} (
                        $fields
                ) ENGINE=MyISAM DEFAULT CHARSET=utf8 
        );
        
        eval{ $self->{DBH}->do($q) };

        return $@ ? undef : 1;
}

# Tabelle entfernen
sub drop_table{
        my $self = shift;
        eval{ $self->{DBH}->do("DROP TABLE $self->{TABN}") };
        return $@ ? undef : 1;
}

# INSERT, nach dem ersten Aufruf liegt das prepared Statement im Objekt
sub insert{
        my $self = shift;
        my %vals = @_; # hash
        
        # Reihenfolge hier egal aber später beim Einbau genauso wie hier!!!
        my @fields = keys %{$self->{FIELDS}};

        # erzeuge prepared Statement
        if(not defined($self->{STH_INSERT})){
                my @qms = ();
                push @qms, "?" for @fields;
                my $q = "INSERT INTO $self->{TABN} (".join(",", @fields).") VALUES(".join(",", @qms).")";
                $self->{STH_INSERT} = $self->{DBH}->prepare_cached($q); 
        }
        
        # Konsistenzprüfung der einzugebenden Werte
        my @input = ();
        foreach my $f(@fields){
                if(my $val = $vals{$f}){
                        push @input, $val;
                }
        }
        eval{ $self->{STH_INSERT}->execute(@input) };

        return $@ ? undef : 1;
}
1;#########################################################################

__END__

# Anwendung im CGI-Script
# Optionen für die Datenbank
my %myopts = (
        base => 'myweb',
        tabn => 'meldeliste',
        user => '',
        pass => '',
        host => 'localhost',
        port => 3306,
);

# Objekterstellung
use Base;
my $o = Base::DBI::CGI->new(%myopts);

# erklärt sich von selbst
#$o->create_table or die "$@";
#$o->drop_table or die "$@";

# Es sind noch die Methoden für den DB-Zugriff zu schreiben
# diese Methoden gehören in die package Base::DBI

# insert funktioniert bereits
$o->insert(
        name => 'Rosti',
        vname => 'Rolf',
        type => 'Flaggschiff',
        descr => 'Meine Zeit bei der Marine',
) or die "$@";



# Du kannst einen HTTP-Header erzeugen
# print $o->header('text/html; charset=UTF-8');

# oder die Parameter erfassen
# my $name = $o->param('name');

Last edited: 2011-07-15 16:02:48 +0200 (CEST)

View full thread Meldeliste auf Website erstellen