counter in php do while loop - counter

I am checking ( or want to check ) if the counter gets to 5 I want to reset the counter back to one and start again until all the records have been read,I have the following code on a test page:
<?php do {
if ($count == 5) { $count = 1;}
echo $count;
echo "<div id=\"col$count\"><div id=\"col$count-content\"><img class=\"resetImg\" name=\"colpic$count\" src=\"assets/images/student_artwork/thumb_" . $row_rsILU['ilu_artwork'] . "\" alt=\"\" style=\"background-color: #999966\"><br><br><span class=\"artistName\">" . $row_rsILU['ilu_fname'] . " " . $row_rsILU['ilu_lname'] . "</span> <br><hr>
Concept Artist<br>
email#artistdomain.ca<br>
416-833-1111<br>
www.portfolio.ca<br>
</div></div>";
$count++;
} while ($row_rsILU = mysql_fetch_assoc($rsILU)); ?>
The record set has three records in it but the count always seems to stop at two and only shows the two images. I am checking the count and if it gets to 5, I want to reset it to 1 and start over again until the total records in the record set have been read. Maybe I am just getting tired but I cannot get this. Would appreciate anyones help on this.
Cheers,
Dave

According to your code, you are trying to echo the row before actually fetching it (I mean the first iteration). Why not just use while loop instead?
<?php
while ($row_rsILU = mysql_fetch_assoc($rsILU)) {
if ($count == 5) { $count = 1;}
echo $count;
echo "<div id=\"col$count\"><div id=\"col$count-content\"><img class=\"resetImg\" name=\"colpic$count\" src=\"assets/images/student_artwork/thumb_" . $row_rsILU['ilu_artwork'] . "\" alt=\"\" style=\"background-color: #999966\"><br><br><span class=\"artistName\">" . $row_rsILU['ilu_fname'] . " " . $row_rsILU['ilu_lname'] . "</span> <br><hr>
Concept Artist<br>
email#artistdomain.ca<br>
416-833-1111<br>
www.portfolio.ca<br>
</div></div>";
$count++;
}
?>
Please let me know if that solves your problem.

Humm ... well now, this is embarrassing! Turns out there was a second, older SELECT statement in the code that I missed and so it was not returning one of the three records because it was not looking for it, based on the older SELECT statement. Sorry about that but thanks for your help.

Related

Issue generating .xls since changing from PHP 5 to PHP 7

I've recently switched from PHP 5.6 to PHP7. A previous PHP script which worked fine in PHP 5.6 is now duplicating columns data in PHP 7. I'm not seeing why. The code:
function cleanData(&$str)
{
$str = preg_replace("/\t/", "\t", $str);
$str = preg_replace("/\r?\n/", "\n", $str);
if(strstr($str, '"')) $str = '"' . str_replace('"', '""', $str) . '"';
// force certain number/date formats to be imported as strings
if(preg_match("/^0/", $str) || preg_match("/^+?\d{8,}$/", $str) || preg_match("/^\d{4}.\d{1,2}.\d{1,2}/", $str))
{
$str = "'$str";
}
}
$day_num = date(d);
$month_num = date(n);
$year_num = date(Y);
// file name for download
$filename = "Subscriber_list_" . $month_num . "-" . $day_num . "-" . $year_num . ".xls";
header("Content-Type: application/vnd.ms-excel");
header("Content-Disposition: attachment;
filename=\"$filename\"");
header('Cache-Control: max-age=0');
echo "ID \t Title \t First Name \t Last Name \t E-Mail \n";
$news_query = mysqli_query("SELECT DISTINCT id, title,firstname, lastname, email FROM users WHERE newsletter = 1 ");
while($row =mysqli_fetch_array($news_query, MYSQL_ASSOC)) {
array_walk($row, 'cleanData');
echo implode("\t", array_values($row)) . "\n";
}
exit;
The DB is fairly standard. Thanks in advance.
I think this is because you're using the MYSQL_ASSOC constant instead of MYSQLI_ASSOC when you fetch rows from the query.
That typo happened to work when you were on PHP 5, because those two constants have the same value. But the MYSQL_ASSOC constant is undefined in PHP 7 since the MYSQL extension has been removed, so mysqli_fetch_array goes with the default behavior of fetching both numeric and associative keys, hence the duplicated columns.
This is solved, Thanks.
I re-wrote the script using:
<pre>
function fetch_assoc($result) {
return mysqli_fetch_assoc($result);
}
</pre>

How to return multiple records from a result set?

I am using perl dbi and getting the sql results however it's coming as an array. The problem is , it only returns 1 array element. I tried to push to get the next element but there is nothing. I am sure (with other tool) I can see there are more then one values. It is (from other tool) I get multiple ddls. With my query I am only getting one of them. Here is my query:
my $rows = $dbh->selectall_arrayref
("show SELECT * FROM TABLE
INNER JOIN TABLE1
ON bla bla ;");
my $len = #$rows;
print $len;
foreach $h (#$rows) {
$st = $h->[0];
$st =~ s/(\d),(\d)/\1|\2/g;
#lines = split/,/,$st;
foreach $x (#lines) {
print FH $x . "\n";
}
}
My question is how do I shift the same array and get next result set from same row? Thanks!
The result of the above code is below:
PRIMARY INDEX ( ProcID ,CollectTimeStamp );ONE)NICODE NOT CASESPECIFIC,,OT NULL,C,
I don't think it brings back the entire content, somehow it is not complete
[This probably counts as "not an answer", but I'm trying to extract more useful information from the OP, and it's far easier to show him the code I want him to run in an answer]
We still really have no idea what you are trying to do here. And, to be honest, I'm not convinced that you do either :-)
Let's have a look at the raw data - without any of the processing that you're adding. Please try running the following code and then edit your question to add the output (if it returns a number of rows, you only need to include a couple).
my $rows = $dbh->selectall_arrayref
("show SELECT * FROM TABLE
INNER JOIN TABLE1
ON bla bla ;");
foreach my $row (#$rows) {
print join(' / ', #$row), "\n";
}
Then, please tell us (using those rows as an example) what output you want.

perltidy formatting multilines

I'm trying to get perltidy to format an if statement like this:
if ($self->image eq $_->[1]
and $self->extension eq $_->[2]
and $self->location eq $_->[3]
and $self->modified eq $_->[4]
and $self->accessed eq $_->[5]) {
but no matter what I try, it insists on formatting it like this:
if ( $self->image eq $_->[1]
and $self->extension eq $_->[2]
and $self->location eq $_->[3]
and $self->modified eq $_->[4]
and $self->accessed eq $_->[5]) {
Also, is there any way to get the last line of this block:
$dbh->do("INSERT INTO image VALUES(NULL, "
. $dbh->quote($self->image) . ", "
. $dbh->quote($self->extension) . ", "
. $dbh->quote($self->location) . ","
. $dbh->quote($self->modified) . ","
. $dbh->quote($self->accessed)
. ")");
to jump up to the previous line like the other lines:
$dbh->do("INSERT INTO image VALUES(NULL, "
. $dbh->quote($self->image) . ", "
. $dbh->quote($self->extension) . ", "
. $dbh->quote($self->location) . ","
. $dbh->quote($self->modified) . ","
. $dbh->quote($self->accessed) . ")");
Here is what I'm currently doing:
perltidy -ce -et=4 -l=100 -pt=2 -msc=1 -bar -ci=0 reporter.pm
Thanks.
I don't have much to offer on the 1st question, but with the 2nd, have you considered refactoring it to use placeholders? It would probably format up better, automaticaly do the quoting for you and give you (and the users of your module) a healthy barrier against SQL injection problems.
my $sth = $dbh->prepare('INSERT INTO image VALUES(NULL, ?, ?, ?, ?, ?)');
$sth->execute(
$self->image, $self->extension, $self->location,
$self->modified, $self->accessed
);
I've also found format skipping: -fs to protect a specific segment of code from perltidy. I'd put an example here but the Site seems to do a hatchet job on it...

Php Command Line Output on the fly

I am writing a command line php script which does some output to the console window, its all look good only issues is when i type
php myfilename.php -....
in the console window, ONLY AFTER its fully executed it outputs the result to the window ..
Wht i want is to do this on the fly like below
customer id: 1223 skipped.
customer id: 22233 added..
...etc
another question is adding \n\r to the printf functions didn't go to a new line ...
any idea on these issues..
This is probably due to output buffering. You can use ob_flush() to flush the buffer manually when needed.
As for your second issue, the correct sequence for newline on Microsoft Windows is "\r\n", not the other way around.
First, the Windows-style end-of-line marker is \r\n, not \n\r. Not many systems ever used \n\r, but they are rare enough that you can forget about them now.
Second, chances are good the output is being block buffered -- you can either use ob_implicit_flush(1) to automatically insert a flush() command after every output command. Or, you could call flush() manually, when you need to flush output.
About the End-Of-Line marker, always use PHP predefined constant PHP_EOL; it is correctly set based on your platform, so you do not have to worry is it right or wrong.
For the [Enter] issue, it could be the output buffering is on. Add this simple test in your script:
function test()
{
$state = array(' added', ' skipped');
for ($i = 0; $i < 50; $i++)
{
echo 'customer id: ' . rand(1, 1000) . $state[rand(0, 1)] . PHP_EOL;
usleep(50000); // slow it a bit to see the line by line output
}
}
// without ob -------------------------------------------
$start = microtime(true);
test();
echo 'Finished in ' . round(microtime(true) - $start, 2) . PHP_EOL . str_repeat('-', 78) . PHP_EOL;
sleep(1);
// with ob ----------------------------------------------
$start = microtime(true);
ob_start(); // if called somewhere at the top in your script
// some previous code...
echo 'Line 1'.PHP_EOL.'Line 2'.PHP_EOL.uniqid().PHP_EOL;
// flush the buffer and stop ob
// this will echo whatever is in the output buffer!
//ob_end_flush();
// or, store the current buffer content in a variable and use it later
$output = ob_get_clean();
test();
echo $output;
echo 'Finished in ' . round(microtime(true) - $start, 2) . PHP_EOL . str_repeat('-', 78) . PHP_EOL;
// you could start buffering again, if needed
ob_start();
For output control functions see http://www.php.net/manual/en/ref.outcontrol.php. They are very powerful tools.
Hope it helps. Cheers!

How do I turn a table into a matrix?

If I got a table in a text file such like
A B 1
A C 2
A D 1
B A 3
C D 2
A E 1
E D 2
C B 2
. . .
. . .
. . .
And I got another symbol list in another text file. I want to transform this table into a Perl data structure like:
_ A D E . . .
A 0 1 1 . . .
D 1 0 2 . . .
E 1 2 0 . . .
. . . . . . .
But I only need some selected symbol, for example A, D and E are selected in the symbol text but B and C are not.
Use an array for the first one and a 2-dimentional hash for the second one. The first one should look roughly like:
$list[0] # row 1 - the value is "A B 1"
And the hash like:
$hash{A}{A} # the intersection of A and A - the value is 0
Figuring out how to implement a problem is about 75% of the mental battle for me. I'm not going to go into specifics about how to print the hash or the array, because that's easy and I'm also not entirely clear on how you want it printed or how much you want printed. But converting the array to the hash should look a bit like this:
foreach (#list) {
my ($letter1, $letter2, $value) = split(/ /);
$hash{$letter1}{$letter2} = $value;
}
At least, I think that's what you're looking for. If you really want you could use a regular expression, but that's probably overkill for just extracting 3 values out of a string.
EDIT: Of course, you could forgo the #list and just assemble the hash straight from the file. But that's your job to figure out, not mine.
you can try this with awk:
awk -f matrix.awk yourfile.txt > newfile.matrix.txt
where matrix.awk is :
BEGIN {
OFS="\t"
}
{
row[$1,$2]=$3
if (!($2 in f2)) { header=(header)?header OFS $2:$2;f2[$2]}
if (col1[c]!=$1)
col1[++c]=$1
}
END {
printf("%*s%s\n", length(col1[1])+2, " ",header)
ncol=split(header,colA,OFS)
for(i=1;i<=c;i++) {
printf("%s", col1[i])
for(j=1;j<=ncol;j++)
printf("%s%s%c", OFS, row[col1[i],colA[j]], (j==ncol)?ORS:"")
}
}
Another way to do this would be to make a two-dimensional array -
my #fArray = ();
## Set the 0,0th element to "_"
push #{$fArray[0]}, '_';
## Assuming that the first line is the range of characters to skip, e.g. BC
chomp(my $skipExpr = <>);
while(<>) {
my ($xVar, $yVar, $val) = split;
## Skip this line if expression matches
next if (/$skipExpr/);
## Check if these elements have already been added in your array
checkExists($xVar);
checkExists($yVar);
## Find their position
for my $i (1..$#fArray) {
$xPos = $i if ($fArray[0][$i] eq $xVar);
$yPos = $i if ($fArray[0][$i] eq $yVar);
}
## Set the value
$fArray[$xPos][$yPos] = $fArray[$yPos][$xPos] = $val;
}
## Print array
for my $i (0..$#fArray) {
for my $j (0..$#{$fArray[$i]}) {
print "$fArray[$i][$j]", " ";
}
print "\n";
}
sub checkExists {
## Checks if the corresponding array element exists,
## else creates and initialises it.
my $nElem = shift;
my $found;
$found = ($_ eq $nElem ? 1 : 0) for ( #{fArray[0]} );
if( $found == 0 ) {
## Create its corresponding column
push #{fArray[0]}, $nElem;
## and row entry.
push #fArray, [$nElem];
## Get its array index
my $newIndex = $#fArray;
## Initialise its corresponding column and rows with '_'
## this is done to enable easy output when printing the array
for my $i (1..$#fArray) {
$fArray[$newIndex][$i] = $fArray[$i][$newIndex] = '_';
}
## Set the intersection cell value to 0
$fArray[$newIndex][$newIndex] = 0;
}
}
I am not too proud regarding the way I have handled references but bear with a beginner here (please leave your suggestions/changes in comments). The above mentioned hash method by Chris sounds a lot easier (not to mention a lot less typing).
CPAN has many potentially useful suff. I use Data::Table for many purposes. Data::Pivot also looks promising, but I have never used it.