I want to download my database by clicking on a button. I have search around and found this code.
yii2 database download
I have added a action on my controller and added this modified code. I've removed database connection in the original code as I guess I don't need to make the connection again. I'm getting error at 'fetch_row()'. I tried Yii::$app->db->createCommand('fetch_row')but still getting error.
define('BACKUP_DIR', 'download/' ) ;
// Define Database Credentials
define('HOST', 'localhost' ) ;
define('USER', 'root' ) ;
define('PASSWORD', 'x24613rt' ) ;
define('DB_NAME', 'panthoibi' ) ;
$files = scandir(BACKUP_DIR);
if(count($files) > 2) {
for ($i=2; $i < count($files); $i++) {
unlink(BACKUP_DIR."/".$files[$i]);
}
}
/*
Define the filename for the sql file
If you plan to upload the file to Amazon's S3 service , use only lower-case letters
*/
$fileName = 'mysqlibackup--' . date('d-m-Y') . '#'.date('h.i.s').'.sql' ;
// Set execution time limit
if(function_exists('max_execution_time')) {
if( ini_get('max_execution_time') > 0 )
set_time_limit(0) ;
}
// Check if directory is already created and has the proper permissions
if (!file_exists(BACKUP_DIR)) mkdir(BACKUP_DIR , 0700) ;
if (!is_writable(BACKUP_DIR)) chmod(BACKUP_DIR , 0700) ;
// Create an ".htaccess" file , it will restrict direct accss to the backup-directory .
//$content = 'deny from all' ;
//$file = new SplFileObject(BACKUP_DIR . '/.htaccess', "w") ;
//$file->fwrite($content) ;
// Introduction information //
$return = "";
$return .= "--\n";
$return .= "-- A mysqli Backup System \n";
$return .= "--\n";
$return .= '-- Export created: ' . date("Y/m/d") . ' on ' . date("h:i") . "\n\n\n";
$return = "--\n";
$return .= "-- Database : " . DB_NAME . "\n";
$return .= "--\n";
$return .= "-- --------------------------------------------------\n";
$return .= "-- ---------------------------------------------------\n";
$return .= 'SET AUTOCOMMIT = 0 ;' ."\n" ;
$return .= 'SET FOREIGN_KEY_CHECKS=0 ;' ."\n" ;
$tables = array() ;
// Exploring what tables this database has
$result = Yii::$app->db->createCommand('SHOW TABLES');
// Cycle through "$result" and put content into an array
while ($row = $result->fetch_row())
$tables[] = $row[0] ;
// Cycle through each table
foreach($tables as $table)
{
// Get content of each table
$result = $mysqli->query('SELECT * FROM '. $table) ;
// Get number of fields (columns) of each table
$num_fields = $mysqli->field_count ;
// Add table information
$return .= "--\n" ;
$return .= '-- Tabel structure for table `' . $table . '`' . "\n" ;
$return .= "--\n" ;
$return.= 'DROP TABLE IF EXISTS `'.$table.'`;' . "\n" ;
// Get the table-shema
$shema = $mysqli->query('SHOW CREATE TABLE '.$table) ;
// Extract table shema
$tableshema = $shema->fetch_row() ;
// Append table-shema into code
$return.= $tableshema[1].";" . "\n\n" ;
// Cycle through each table-row
while($rowdata = $result->fetch_row())
{
// Prepare code that will insert data into table
$return .= 'INSERT INTO `'.$table .'` VALUES ( ' ;
// Extract data of each row
for($i=0; $i<$num_fields; $i++)
$return .= '"'.$rowdata[$i] . "\"," ;
// Let's remove the last comma
$return = substr("$return", 0, -1) ;
$return .= ");" ."\n" ;
}
$return .= "\n\n" ;
}
$return .= 'SET FOREIGN_KEY_CHECKS = 1 ; ' . "\n" ;
$return .= 'COMMIT ; ' . "\n" ;
$return .= 'SET AUTOCOMMIT = 1 ; ' . "\n" ;
//$file = file_put_contents($fileName , $return) ;
$zip = new ZipArchive() ;
$resOpen = $zip->open(BACKUP_DIR . '/' .$fileName.".zip" , ZIPARCHIVE::CREATE) ;
if( $resOpen )
$zip->addFromString( $fileName , "$return" ) ;
$zip->close() ;
$fileSize = $this->get_file_size_unit(filesize(BACKUP_DIR . "/". $fileName . '.zip')) ;
You are mixing Yii query command with mysqli command this don't work ..
eg:
You are using CreateCommand
// Exploring what tables this database has
$result = Yii::$app->db->createCommand('SHOW TABLES');
but don't execute .. you should try
$result = Yii::$app->db->createCommand('SHOW TABLES')->execute();
or
$result = Yii::$app->db->createCommand('SHOW TABLES')->queryOne();
or
$result = Yii::$app->db->createCommand('SHOW TABLES')->queryAll();
Then try take a look at the $result content eg:
var_dump($result);
Your $result content don't shoul be adapt for
$result->fetch_row()
but eventually you can iterate or manage the actual $result content with php function ..
Related
I've looked for a solution to this here on stack overflow and elsewhere, but can't find examples that deal with the volume I have to work with. If I have missed a solution to this that has been posted elsewhere, I'd be very grateful if someone could point me into the right direction.
I'm trying to import time series data from 45 different Excel worksheets (about 5 per Excel workbook). Each worksheet contains commodity price series, covering several years of daily prices for each commodity.
The raw Excel data has one row for each day for which prices might exist and one column for each commodity contract, which typically is a monthly future contract. The points for each contract hence are at least 30 each (but not much more) while the entire table has several thousand rows and 100+ columns.
I was able to build a SSIS package that reads the data and using unpivot, transforms the matrix into row based records with columns for:
Date, Price, Contract
The problem however is that in the unpivot transform I have to manually specify the destination column for each transformed input column. So 45 worksheets, each containing 100+ columns (some even several hundred) for contracts I'd be ending up 'hard-coding' those transforms manually for the next few days... On top, this is not as flexible/re-usable as I was hoping.
Example of the raw data attached (the entire Cocoa worksheet contains 9724 rows and 195 columns)
Here's how the unpivot for another single commodity is configured. The 'Destination Column' has to be filled in manually row-by-row.
I'm hoping that I have just missed the right steps in the unpivot configuration to make these columns dynamic. Ideally the SSIS solution can be re-used with equally formatted Excel workbooks later again. It's not required to run this on the Server as it's not a frequently recurring thing but rather once or twice per year max. So i can easily kick this off manually from within VS.
I'm trying to help an academic researcher who would otherwise spend a massive amount of time cleaning and analysing the data manually in Excel.
First you need to design and create the tables that are going to receive the data and experiment with some manual data entry to check the data model.
Make sure each spreadsheet has enough header information to know how to process the rows.
When that is done, I would save the sheets to text files with tab delimiters.
Next I would write a loading program in Perl. It reads the header rows first and determines the rules for inserting the rows into the database. Then each row gets converted into an insert into the database.
Here is an example from an invoice loading program I own (all rights):
if ($first) {
$obj->_hdr2keys(0); # convert spreadhseet header into a lookup
my $hdr = $obj->_copystruct($obj->{ar}[0]);
my #Hhdr = ('invoice header id');
my #Hcols = ('invhid');
my #Htypes = ('serial');
my #Dhdr = ('invoice detail id');
my #Dcols = ('invdid','invhid');
my #Dtypes = ('serial','integer');
for (my $col=0; $col <= $#{$hdr}; $col++) {
my $colname = lc($obj->_pomp($hdr->[$col]));
if ($colname eq 'invoicenumber') {
push #Hhdr, $hdr->[$col];
push #Hcols, $colname;
push #Htypes, 'char(32)';
}
elsif ($colname eq 'buysell') {
push #Hhdr, $hdr->[$col];
push #Hcols, $colname;
push #Htypes, 'boolean';
}
elsif ($colname eq 'suppliercustomer') {
push #Hhdr, $hdr->[$col];
push #Hcols, $colname;
push #Htypes, 'char(64)';
}
elsif ($colname eq 'date') {
push #Hhdr, 'Transaction Date';
push #Hcols, 'transactiondate';
push #Htypes, 'date';
}
elsif ($colname eq 'article') {
push #Dhdr, 'Article id';
push #Dcols, 'artid';
push #Dtypes, 'integer';
push #Dhdr, 'Article Description';
push #Dcols, 'description';
push #Dtypes, 'char(64)';
}
elsif ($colname eq 'qty') {
push #Dhdr, $hdr->[$col];
push #Dcols, $colname;
push #Dtypes, 'integer';
}
elsif ($colname eq 'priceexclbtw') {
push #Dhdr, $hdr->[$col];
push #Dcols, $colname;
push #Dtypes, 'double precision';
}
elsif ($colname eq 'btw') {
push #Dhdr, $hdr->[$col];
push #Dcols, $colname;
push #Dtypes, 'real';
}
}
$obj->_getset('INVHar',
['invoiceheader',
['PK','invhid'],
['__COLUMNS__'],
\#Hcols,
\#Htypes,
\#Hhdr
]
);
$obj->_getset('INVDar',
['invoicedetail',
['PK','invdid'],
['FK','invhid','invoiceheader','invhid'],
['FK','artid','article','artid'],
['__COLUMNS__'],
\#Dcols,
\#Dtypes,
\#Dhdr
]
);
}
$first = 0;
SALESROW: for (my $i=1; $i <= $#{$obj->{ar}}; $i++) {
my #Hrow = ('');
my #Drow = ('');
my $date = $obj->_selectar('', $i, 'Date');
$date =~ s/\-/\//g;
if ($date) {
$obj->_validCSV('date', $date)
or die "CSV format error date |$date| in file $file";
}
my $invtotal = ($obj->_selectar('', $i, 'Invoice Total incl. BTW'));
my $article = $obj->_selectar('', $i, 'Article');
$date or $article or next SALESROW;
if ($date) {
push #Hrow, $obj->_selectar('', $i, 'Invoice Number');
my $buysell = $obj->_selectar('', $i, 'Buy/Sell');
push #Hrow, ($buysell eq 'S') ? 1 : 0;
push #Hrow, $obj->_selectar('', $i, 'Supplier/Customer');
push #Hrow, $date;
push #{$obj->_getset('INVHar')}, \#Hrow;
$invhid++;
}
push #Drow, $invhid;
if ($article eq 'E0154') {
push #Drow, 1;
}
elsif ($article eq 'C0154') {
push #Drow, 2;
}
elsif ($article eq 'C0500') {
push #Drow, 3;
}
elsif ($article eq 'C2000') {
push #Drow, 4;
}
elsif ($article eq 'C5000') {
push #Drow, 5;
}
else {
die "unrecognised sales article $article\n"
. Dumper($obj->{ar}[$i]);
}
push #Drow, undef; # description is in article table
push #Drow, $obj->_selectar('', $i, 'Qty.');
push #Drow, $obj->_selectar('', $i, 'Price excl. BTW');
push #Drow, $obj->_selectar('', $i, 'BTW %');
push #{$obj->_getset('INVDar')}, \#Drow;
}
This creates header and detail records for invoices after the product table has already been loaded from another spreadsheet.
In the above example two array of arrays are created, INVHar and INVDar. When they are ready, the calling routine loads them into the database as follows. In this next code example the tables are created as well as the rows and also a metadb is updated for loading of future tables and managing foreign keys for existing tables. The array created in the previous snippet contains all information needed to create the table and insert the rows. There is also a simple routine _DBdatacnv that converts between the formats in the spreadsheet and the formats needed in the database. For example, the spreadsheet had currency symbols that need to be stripped before insertion.
sub _arr2db {
my ($obj) = #_;
my $ar = $obj->_copystruct($obj->_getset('ar'));
my $dbh = $obj->_getset('CDBh');
my $mdbh = $obj->_getset('MDBh');
my $table = shift #$ar;
$mdbh->{AutoCommit} = 0;
$dbh->{AutoCommit} = 0;
my #tables = $mdbh->selectrow_array(
"SELECT id FROM mtables
WHERE name = \'$table\'"
);
my $id = $tables[0] || '';
if ($id) {
$mdbh->do("DELETE FROM mcolumns where tblid=$id");
$mdbh->do("DELETE FROM mtables where id=$id");
}
# process constraints
my %constraint;
while ($#{$ar} >= 0
and $ar->[0][0] ne '__COLUMNS__') {
my $cts = shift #$ar;
my $type = shift #$cts;
if ($type eq 'PK') {
my $pk = shift #$cts;
$constraint{$pk} ||= '';
$constraint{$pk} .= ' PRIMARY KEY';
#$cts and die "unsupported compound key for $table";
}
elsif ($type eq 'FK') {
my ($col, $ft, $fk) = #$cts;
$ft && $fk or die "incomplete FK declaration in CSV for $table";
$constraint{$col} ||= '';
$constraint{$col} .=
sprintf( ' REFERENCES %s(%s)', $ft, $fk );
}
elsif ($type eq 'UNIQUE') {
while (my $uk = shift #$cts) {
$constraint{$uk} ||= '';
$constraint{$uk} .= ' UNIQUE';
}
}
elsif ($type eq 'NOT NULL') {
while (my $nk = shift #$cts) {
$constraint{$nk} ||= '';
$constraint{$nk} .= ' NOT NULL';
}
}
else {
die "unrecognised constraint |$type| for table $table";
}
}
shift #$ar;
unless ($mdbh->do("INSERT INTO mtables (name) values (\'$table\')")) {
warn $mdbh->errstr . ": mtables";
$mdbh->rollback;
die;
}
#tables = $mdbh->selectrow_array(
"SELECT id FROM mtables
WHERE name = \'$table\'"
);
$id = shift #tables;
$dbh->do("DROP TABLE IF EXISTS $table CASCADE")
or die $dbh->errstr;
my $create = "CREATE TABLE $table\n";
my $cols = shift #$ar;
my $types = shift #$ar;
my $desc = shift #$ar;
my $first = 1;
my $last = 0;
for (my $i=0; $i<=$#{$cols}; $i++) {
$last = 1;
if ($first) {
$first = 0;
$create .= "( "
}
else {
$create .= ",\n";
}
$create .= $cols->[$i]
. ' ' . $obj->_DBcnvtype($types->[$i]);
$constraint{$cols->[$i]}
and $create .= ' ' . $constraint{$cols->[$i]};
unless ($mdbh->do("INSERT INTO mcolumns (tblid,name,type,description)
values ($id,\'$cols->[$i]\',\'$types->[$i]\',\'$desc->[$i]\')"))
{
warn $mdbh->errstr;
$mdbh->rollback;
die;
}
}
$last and $create .= ')';
unless ($dbh->do($create)) {
warn $dbh->errstr;
$dbh->rollback;
die;
}
my $count = 0;
while (my $row = shift #$ar) {
$count++;
my $insert = "INSERT INTO $table (";
my $values = 'VALUES (';
my $first = 1;
for (my $i=0; $i<=$#{$cols}; $i++) {
my $colname = $cols->[$i];
unless (defined($constraint{$colname})
and $constraint{$colname} =~ /PRIMARY KEY/) {
if ($first) {
$first = 0;
}
else {
$insert .= ', ';
$values .= ', ';
}
$insert .= $colname;
my $val = $obj->_DBdatacnv('CSV', 'DB',
$types->[$i],$row->[$i]);
if ($val eq '%ABORT') {
$mdbh->rollback;
die;
}
$values .= $val;
}
}
$insert .= ')' . $values . ')';
unless ($dbh->do($insert)) {
warn $dbh->errstr;
warn $insert;
$mdbh->rollback;
die;
}
}
NOINSERT: $mdbh->commit;
$dbh->commit;
# warn "inserted $count rows into $table";
}
Update: ok I'll add the generic routine that converts from CSV to array ready for _arr2db above for all other cases I have for a system: The spreadsheets are first augmented with PK FK and other constraints followed by a header of column names for the database, a row of the database types (notional, actual are taken care of in _DBcnvdatatype) then a row of tags that go in the metadatabase and finally a token COLUMNS just before the rows of data to insert.
sub _csv2arr {
my ($obj, $csv ) = #_;
my $ar = [];
my $delim = $obj->_getset('csvdelim') || '\,';
my $basename = basename($csv);
$basename =~ s/\.txt$//;
$ar = [$basename];
open my $fh, $csv
or die "$!: $csv";
while (<$fh>) {
chomp;
my $sa = [];
#$sa = split /$delim/;
push #$ar, $sa;
}
close $fh;
$obj->{ar} = $ar;
}
I would do this as a series of nested loops:
Loop 1, iterate through all files in the folder. pass the file name to next loop
Loop 2 Open File, Iterate through sheets
Loop 3 in sheet X, Loop through the columns (A) > 1
Loop 4 - Loop through rows:
Read sheet X, Row B,
Get values from (Row B, Column 1) as Date, (Row 1, Column A) as Product. (Row B, Column A) as Price - write to destination.
End Loop 4
(optional, at the end of the column record some meta data about number of rows )
End of Loop 3
(optional, record some meta data about the number of columns in the sheet)
End of Loop 2
(optional, record some meta data about the number of sheets in file X)
End of Loop 1
(strongly suggested - record some meta data about the file X and number of sheets/rows/columns - you can test a sample later for your own confidence)
You may want to modify a copy of one of your files so that you can test for issues.
sheet empty
invalid data
missing header
text instead of price
This will give more confidence and will shorten the rework that is required when you discover new edge cases.
Final output table should be the denormalised data in 3 columns:
Date,
Product,
Price
EDIT
Here is a link that shows how you can dynamically loop through the columns of an Excel spreadsheet (and sheets) so that you can use this process to unpivot the data to a normalised form
Looping through Excel columns in SSIS
I'm trying to get the following Perl program to print a default value, if no result is returned from a query. I am not sure how to do that.
When I run the script, I get the error: Can't call method "country_name" on an undefined value. Are there Any ideas on how I can change the program to print a default value, if no results are returned?
#!/usr/bin/perl update IP addresses with country
use strict;
use warnings;
use Net::IPInfoDB;
my $psql = "/usr/local/pgsql/current/bin/psql";
my $db = 'cpi';
my $args = "-U postgres -qc";
my $date = `/bin/date +\%y\%m\%d%H`;
my $reportfile = "/tmp/multiiplogins-$date";
my $sendmail = "/usr/sbin/sendmail -t -fcpi\#user.com";
my $mailsubject = "Login Report";
my $mailto = 'email#user.com';
my $query = "SELECT userid, login, email, logins, ips FROM (SELECT userid,login,email, count(userid) AS logins, count(ipaddr) AS ips FROM (SELECT l.userid, u.login, u.email, l.ipaddr FROM synloginaccess l, synusers u$
my $query2 = "SELECT l.userid, login, email, ipaddr FROM synloginaccess l, synusers u where l.accesstime > (now() - interval '24 hours') and l.type=2 and l.userid=u.userid ORDER BY l.userid;";
open (REPORT, ">$reportfile");
my $command = qq/$psql $db $args "$query"/;
my $command2 = qq/$psql $db $args "$query2"/;
my $result = `$command`;
my $result2 = `$command2`;
my $g = Net::IPInfoDB->new;
$g->key("api_key");
#we split $login into an array, line-by-line
my #lines = split("\n", $result2);
for my $line (#lines) {
#now we iterate through every line one-by-one
if ($line =~ /(?<ip>\d+\.\d+\.\d+\.\d+)/) {
my $city = $g->get_city("$1");
my $addr = $g->get_country("$1");
print "$line " . "| " . "\t" . $city->city_name . ", " . $addr->country_name ."\n";
print REPORT "$line " . "| " . "\t" . $city->city_name . ", ". $addr->country_name ."\n";
}
else {
print "$line \n ";
}
}
close REPORT;
mailReport();
sub mailReport{
#mail it
open(MAIL, "|$sendmail");
print MAIL "To: $mailto\n";
print MAIL "Subject: $mailsubject\n";
print MAIL "\n";
open (INFILE, "$reportfile");
my #contents = <INFILE>;
my $line;`
$addr ? $addr->country_name : "default"
I can't manage to backup my MySQL database. I use the following command:
mysqldump --user=user --password=password db > db.sql
This is what the output file looks like:
-- MySQL dump 10.11
--
-- Host: localhost Database: db
-- ------------------------------------------------------
-- Server version 5.0.96-community
/*!40101 SET #OLD_CHARACTER_SET_CLIENT=##CHARACTER_SET_CLIENT */;
/*!40101 SET #OLD_CHARACTER_SET_RESULTS=##CHARACTER_SET_RESULTS */;
/*!40101 SET #OLD_COLLATION_CONNECTION=##COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET #OLD_TIME_ZONE=##TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET #OLD_UNIQUE_CHECKS=##UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET #OLD_FOREIGN_KEY_CHECKS=##FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET #OLD_SQL_MODE=##SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET #OLD_SQL_NOTES=##SQL_NOTES, SQL_NOTES=0 */;
That's it. Not any CREATE TABLE and not any INSERT... I also noticed in posts for similar problems that there always was a -- Dump completed on YYYY-MM-DD HH:MM:SS at the end of the output, which is not the case here. My username and my password are correct and the user has all possible privileges.
What am I doing wrong?
Try this:
mysqldump -u username -p DB_Name > dumpfile.sql
Try the same but with the normal mysql command, ie, if you have
mysqldump --user=root --password=secret db
then try
mysql --user=root --password=secret db
You should be able to see all tables and data that way, if you're not it's probably the user that's wrong.
Since asking this question, my web host deactivated the shell_exec() command, so now I'm using a PHP script to backup my database. Here's the function I'm using:
function backup_tables($host, $user, $pass, $name, $tables='*', $backup_path) {
$link = mysql_connect($host,$user,$pass);
mysql_select_db($name,$link);
//get all of the tables
if($tables == '*') {
$tables = array();
$result = mysql_query('SHOW TABLES');
while($row = mysql_fetch_row($result)) {
$tables[] = $row[0];
}
}
else {
$tables = is_array($tables) ? $tables : explode(', ',$tables);
}
$droptables = 'DROP TABLE IF EXISTS ';
for ($i = sizeof($tables) - 1; $i >= 0; $i--) {
$droptables .= '`' . $tables[$i] . '`';
if ($i > 0) {
$droptables .= ', ';
} else {
$droptables .= ';';
}
}
//cycle through
foreach($tables as $table) {
$result = mysql_query('SELECT * FROM '.$table);
$num_fields = mysql_num_fields($result);
// $droptables.= '`' . $table . '`, ';
$row2 = mysql_fetch_row(mysql_query('SHOW CREATE TABLE '.$table));
$data .= "\n\n".$row2[1].";\n\n";
for ($i = 0; $i < $num_fields; $i++) {
while($row = mysql_fetch_row($result)) {
$data .= 'INSERT INTO '.$table.' VALUES(';
for ($j = 0; $j < $num_fields; $j++) {
if (isset($row[$j])) {
$row[$j] = addslashes($row[$j]);
$row[$j] = ereg_replace("\n","\\n",$row[$j]);
$data .= '"'.$row[$j].'"' ;
} else {
$data .= 'NULL';
}
if ($j < ($num_fields-1)) {
$data .= ',';
}
}
$data .= ");\n";
}
}
$data .= "\n\n\n";
}
$return = $droptables . $return;
//save file
$date = date('Ymd-His');
$filename = 'db-backup-' . $date . '.sql';
$handle = fopen($backup_path.$filename,'w+');
fwrite($handle, utf8_encode($return));
fclose($handle);
$gzfile = $filename . '.gz';
$handle = gzopen($backup_path.$gzfile, 'w9');
gzwrite($handle, file_get_contents($backup_path.$filename));
gzclose($handle);
}
Example usage: backup_tables('localhost','user','pass','database', 'users, posts, comments, subscriptions', '/home/user/db_backups/');. You just have to remember to put the tables with foreign keys at the end of the list.
Try this mysql -u root -p db_name < mydb.sql
This worked for me. Please try it once
mysql -u <username> -p"<password>" database_name < sqlfile.sql
I have a Perl script which takes a file as input and has PL/SQL (for statements and DBMS_OUTPUT.PUT_LINE) in it. I need to run make a database connection and run that file in Perl script.The pl/sql has Begin declare end section,with for statements on it which is writing data of 3 columns separated using commas(DBMS_OUTPUT.PUT_LINE) I have shown what I have tried below. Is it correct?
my $dbh = DBI->connect( "dbi:Oracle:$db", $username, $passwd ) ||
die( $DBI::errstr . "\n" );
$dbh->{AutoCommit} = 0;
$dbh->{PrintError} = 1;
open FILE, $sql_file or die "Could not open file";
$query = '';
while($line = <FILE>) {
chomp($line);
$query .= $line;
}
my $sth = $dbh->prepare($query);
$sth->execute();
while ( my #row = $sth->fetchrow_array() ) {
foreach (#row) {
print "$_";
}
print "\n";
}
$sth->fetch(), $sth->fetchrow_*(), and friends all fetch records from a result set. In Oracle PL/SQL blocks don't normally return result sets. So calling $sth->fetchrow_array() after running a PL/SQL block won't return any results.
If your using DBMS_OUTPUT.PUT_LINE to output results you will need to use the dbms_output_* functions provided by DBD::Oracle.
my $dbms_output_byte_limit = 1000000;
$dbh->func( $dbms_output_byte_limit, 'dbms_output_enable' );
my $sth = $dbh->prepare($query);
$sth->execute();
my #text = $dbh->func( 'dbms_output_get' );
After that someone registers in a site, a mail is usually sent to his mail account. But to generate this link or what info can be placed in this link so that it can be used to activate the user account??
you can place any thing which can identify a valid user
1- A Hash Value
2- An Encrypted String
3- A Guid
and when user clicks on the link , you can validate the value.
Check this part of code:
Generate code and e-mail:
/* if $acces = 0 everything is perfect so the system send a confirmation mail */
if($acces == 0)
{
print("<br>A mail has been send to " . $mail . "<br><br>") ;
/* prepare the vars */
$activ = $user . $pass ;
$code = md5($activ) ;
/* to how send to mail */
$to = $mail ;
/* prepare the subject */
$subject = "You need to confirm you registration to " . $_SERVER['HTTP_HOST'] ;
/* start writing the message */
$message = "Hello " . $user . ",\r\n\r\n" ;
$message .= "Thank you for registering at " . $_SERVER['HTTP_HOST'] . " Your account is created and must be activated before you can use it.\r\n" ;
$message .= "To activate the account click on the following link or copy-paste it in your browser :\r\n\r\n" ;
$message .= "http://" . $_SERVER['HTTP_HOST'] . "/~carron/registration/register_send.php?user=" . $user . "&activation=" . $code . "\r\n\r\n" ;
$message .= "After activation you may login to http://" . $_SERVER['HTTP_HOST'] . " using the following username and password:\r\n\r\n" ;
$message .= "Username - " . $user . "\r\nPassword - " . $pass . "\r\n" ;
/* To send HTML mail, you can set the Content-type header. */
$headers = "MIME-Version: 1.0";
$headers .= "Content-type: text/html; charset=iso-8859-1";
/* set up additional headers */
$headers .= "To: " . $to . "<br>\n" ;
$headers .= "From: " . $from . $addmail ;
/* writing data in the base */
$query = "INSERT INTO registration (user, pass, activ, mail) VALUES ('$user', '$pass', '$code', '$mail') ;" ;
$result = mysql_query($query, $db);
if ($result == false)
die("Failed " . $query);
else
{
/* everything went well so we can mail it now */
mail($to, $subject, $message, $headers);
}
}
Check activation:
/* controle if the validation link is right */
$x = 0 ;
$query = "SELECT user, pass, activ, mail FROM registration WHERE user = '" . $username . "';" ;
$result = mysql_query($query, $db);
if ($result == false) die("Failed " . $query);
while ($fields = mysql_fetch_row($result))
{
for ($i=0, $max=sizeof($fields) ; $i < $max ; $i++)
{
$tmp[$i] = $fields[$i] ;
}
/* the activation link is right so we can update
the datas in the data base */
if($activation == $tmp[2] AND $username == $tmp[0])
{
$x = 1 ;
$query2 = "UPDATE registration SET activated = '1' WHERE user = '" . $username . "' AND activ = '" . $activation . "' ;" ;
$result2 = mysql_query($query2, $db);
if ($result2 == false)
die("Failed " . $query2);
}
else
$x = -1 ;
}
/* give a confirmation message to the user */
if($x == 1)
print($username . " your activation has been done perfectly<br> Thank you...") ;
else
print($username . " your activation has not been done corectly<br> Please try again later...") ;
Script from PHPclasses.org
The idea is to have a link that only the recipient of the email knows. So when that link is visited on your site, you know that someone has read the email you sent and clicked on the link and so you can presume that the person who registered and the person who read the email are the same.
As such, you just need a link that can't be easily guessed. Pick something random (and record it in the user's profile) or hash the user name + a seed, or something.
When user registered, you can use uniqid() to create an activate code and stored in database. Then in mail, give a link like: http://....../activate.php?code=[uniqid()]
In activate.php, you can read activate code from database and check it.