php only first digit in mySQL - php

I am trying to output randomly generated values via "echo" command and write them to a database. The "echo" output is no problem, but in the mySQL table only the first digit of the generated number is given. In theory there should be displayed five digits. https://i.stack.imgur.com/1KPGi.png
if ($submitbutton){
$length = 5;
$chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz##$&*";
$size = strlen( $chars );
echo "Key: ";
for( $i = 0; $i < $length; $i++ ) {
$str= $chars[ rand( 0, $size - 1 ) ];
echo $str;
$sql = "INSERT INTO regkey (regkey) VALUES (?)";
$stmt = mysqli_prepare($link, $sql);
$str1 = $str;
mysqli_stmt_bind_param($stmt, "s", $str1);
mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt);
mysqli_close($link);
}
If I try to enter another predefined value via php, this works without problems.

This is nothing to do with your database.
In your for loop, you overwrite $str with a single character every time the loop runs. I guess you intended to append to it instead using .=. (N.B. This logical flaw is masked by the fact you echo within the loop, so on screen you see what looks like a single string but is in fact 5 separate strings right next to each other.)
You then also run the INSERT the same number of times, so you get 5 separate entries, one for each digit (although since you close the connection within the loop and then don't re-open it, it's hard to see how that is actually succeeding - I'd guess the 2nd query fails and you either didn't mention the error or have suppressed all error reporting so you didn't see it).
It was little unclear, but I think you wanted to generate one 5-digit string and write it all to the same row in the database? If so, then do it like this:
if ($submitbutton){
$length = 5;
$chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz##$&*";
$size = strlen( $chars );
echo "Key: ";
$str = "";
for( $i = 0; $i < $length; $i++ ) {
$str .= $chars[ rand( 0, $size - 1 ) ]; //append not overwrite
}
//after the loop has finished, do the echo and insert once only
echo $str;
$sql = "INSERT INTO regkey (regkey) VALUES (?)";
$stmt = mysqli_prepare($link, $sql);
mysqli_stmt_bind_param($stmt, "s", $str);
mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt);
mysqli_close($link);
N.B. As suggested in the comments, you could also replace the for loop entirely with
$str = substr(str_shuffle($chars), 0, $length);
which will do the same job for you using existing PHP functions.

Related

Mysqli Wild Card Insert with data range

I have a very large data (not a file) to insert into a students' database. It will be very difficult to type every inch of it, loop and insert. However, it follows a specific pattern and it's in a range of specific numbers.
Below is an example of what I am talking about.
Student's Reference Numbers
Sample range: APS00001 - APS02000
The first three characters are constant. but the rest are not. The data has to be inserted based on the given range.
<?php mysqli_query($conn,"INSERT INTO table (reference) VALUES('each of the data in the sample range')"); ?>
So I could generate the sequence using this code
<?php
$array_items = array();
for ($i=0; $i <= 2000; $i++) {
$array_items[] .= $i;
}
print_r($array_items); // prints the sequence
?>
Here is an SQL solution to your INSERT problem.
Run this to loop from 1 to 2000. It generates APS0001, padding the number as it goes.
DELIMITER $$
DROP PROCEDURE IF EXISTS insert_data $$
CREATE PROCEDURE insert_data ()
BEGIN
DECLARE count INT DEFAULT 1;
WHILE count <= 2000 DO
INSERT INTO `tbl1`(`col3`) VALUES(CONCAT("APS",LPAD(count, 4, '0')));
SET count = count + 1;
END WHILE;
END $$
DELIMITER ;
CALL insert_data();
Since the original post was updated, here is a PHP solution:
<?php
// add $conn info
for ($i = 1; $i <= 2000; $i++) {
$insdata = "APS" . str_pad($i, 5, "0", STR_PAD_LEFT);
mysqli_query($conn,"INSERT INTO table (reference) VALUES('$insdata')");
}
?>
You should use prepared statement with parameter binding. To pad the string to a given length use str_pad(). You can prepend the APS string either in PHP or in SQL using CONCAT().
$sql = "INSERT INTO table (reference) VALUES(CONCAT('APS', ?))";
$stmt = $db->prepare($sql);
$stmt->bind_param('s', $value_to_be_inserted);
$array_items = array();
for ($i = 1; $i < 20; $i++) {
$array_items[] .= +$i;
$value_to_be_inserted = str_pad($i, 5, '0', STR_PAD_LEFT);
$stmt->execute();
}
Don't prepare in the loop. Only execute inside the loop.

Counting vowels in a text file with PHP

I'm trying to count the vowels in a lengthy text, provided by a .txt file. I can successfully open the file and echo it out into the browser. What I can't seem to do is get my script to do the actual vowel counting and I'm not entirely sure why. I'm supposed to output the vowel count to a file that doesn't previously exist, but is referred to as "file_output1.txt". I'm not sure if this is what is causing the issue, or if I'm not properly accessing the text file (Assignment Input) to enable the count to occur, or if I made a syntax error my eyes just can't seem to catch right now.
This is what I've done so far, but I'm not getting the count to fill. There are hundreds of vowels in the text file and it keeps spitting out: "There are (0) vowels". I have counted letters in a string before, but I am having trouble doing it with the file. Any advice?
<?php
#openfile
$file = "Assignment2inputfile.txt" ;
$document = fopen($file,r);
echo fread($document,filesize("Assignment2inputfile.txt"));
?>
<html>
<br><br>
</html>
<?php
#vowelcount
$vowels = array("a", "e", "i", "o", "u");
$length = strlen($_POST["file_output1.txt"]);
$count = 0;
for ($i =0; $i = $length; $i++)
{
if (array_search($_POST["file_output1.txt"][$i], $vowels))
{
$count++;
}
}
echo 'There are (' . $count . ') vowels ' . $_POST["file_output1.txt"] .'.';
fclose($document);
?>
I have counted letters before, but this time it is not a short string input. How can I do this for vowels, but with a FILE instead of a string?
You could use a regex to do this quite simply
$text='The quick brown fox jumped over the lazy dog';
$pttn='#[aeiouAEIOU]#';
preg_match_all( $pttn, $text, $matches );
printf( '<pre>%s</pre>',print_r( $matches, true ) );
printf('There are %d vowels',count($matches[0]));
The array_search is meant for finding a key of a value inside an array. But, you want to count the number of vowels in a string.
Since you have already read the entire file into memory, one simple approach here would be to just strip all vowels, and then compare the length of the resulting string against the original length:
$text = $_POST["file_output1.txt"];
$length = strlen($text);
$new_text = preg_replace("/[aeiou]/i", "", $text);
echo "Number of vowels: " . ($length - strlen($new_text));
Here is a brief demo showing that the above logic is working:
Demo
Here, I have updated code.
<?php
$file = "Assignment2inputfile.txt";
$document = fopen($file, 'r');
$output = fread($document, filesize("Assignment2inputfile.txt"));
$vowels = array(
"a",
"e",
"i",
"o",
"u"
);
$length = strlen($output);
$count = 0;
for ($i = 0; $i < $length; $i++) {
if (array_search($output[$i], $vowels)) {
$count++;
}
}
echo 'There are (' . $count . ') vowels ' . $count . '.';
fclose($document);
?>
I don't quite understand, are you trying to echo the file then read it via $_POST ???. That wouldn't work. If you're using a single php file then try
$file = "Assignment2inputfile.txt" ;
$document = fopen($file,r);
$str = fread($document,filesize("Assignment2inputfile.txt"));
Now you can use $str as
$vowels = array("a", "e", "i", "o", "u");
$length = strlen($str);
$count = 0;
for ($i =0; $i = $length; $i++)
{
if (array_search($str[$i], $vowels))
{
$count++;
}
}
finally write it to required file.
P.S I haven't completely understood your question but this should help if you're trying a normal read from a local file.
Based on this:
I'm trying to count the vowels in a lengthy text, provided by a .txt
file[...] I have counted letters in a string before, but I am having
trouble doing it with the file. Any advice?
You can use the following line of code to count only vowels in a file
str_ireplace(['a','e','u','i','o'],' ',file_get_contents('Assignment2inputfile.txt'),$count);
We basically simulate an insensitive case replacement while keeping track of the number of replacements which give exactly what you need the number of vowels
Then based on this:
I'm supposed to output the vowel count to a file that doesn't
previously exist, but is referred to as "file_output1.txt".
file_put_contents("file_output1.txt",sprintf('There are %d vowels ',$count));
we use this line of code to create a new file if not exists and put a formatted string with the number of vowels as expected.
First possibility that you are sending $_POST['file_output1.txt'] from another file to here displayed file.
if you are not getting any POST data or All you have is here displayed sample file, then my friend you are wrong, you have to take form and form fields like text-field, textarea etc,
and you have to submit it at here displayed file with post request so you can take $_POST variable, i am assuming that you are doing right then your code is fine except it has 2 errors like below:
Notice: Use of undefined constant r - assumed 'r' in C:\xampp\htdocs\stackplay\count_vowels.php on line 4
You have used (file operation mode) r in fopen($file,'r') function without quote , it should be in single or double quote
see the syntax here fopen (string $filename , string $mode)
second error is logical error in for loop You have written for ($i =0; $i = $length; $i++) so it will assign length of file content to $i in first iteration and loop runs infinitely still occur execution time out or allocated memory exhausts, so to solve it replace it with for ($i =0; $i < $length; $i++)
Second Possibility that you are not getting any POST data or All you have is file displayed in sample code in question, then i am giving you solution as below:
Assignment2inputfile.txt File:
The quick brown fox jumped over the lazy dog
count_vowels.php File:
<?php
#openfile
$file = "Assignment2inputfile.txt" ;
$document = fopen($file,'r');
$text = fread($document,filesize("Assignment2inputfile.txt"));
fclose($document);
?>
<html>
<br><br>
</html>
<?php
#vowelcount
$vowels = array("a", "e", "i", "o", "u");
$length = strlen($text);
$count = 0;
for ($i =0; $i < $length; $i++)
{
if (array_search($text[$i], $vowels))
{
$count++;
}
}
echo 'There are (' . $count . ') vowels in : ' . $text .'.';
?>
//Output:
//There are (11) vowels in : The quick brown fox jumped over the lazy dog.
There can be lots of solution to count vowels from text file but i am only showing how to do it rightly, please comment if anywhere i am wrong, thanks.

PHP mysqli insert only works once

I've got a script that I needed to change since the data which is going to be inserted into the db got too big to do it at once. So I created a loop, that splits up the array in blocks of 6000 rows and then inserts it.
I don't know exactly if the data is to big for the server to process at once or if it's too big to upload, but atm I got both steps split up in these 6000s blocks.
Code:
for ($j = 0; $j <= ceil($alength / 6000); $j++){
$array = array_slice($arraysource, $j * 6000, 5999);
$sql = "INSERT INTO Ranking (rank, name, score, kd, wins, kills, deaths, shots, time, spree) VALUES ";
foreach($array as $a=>$value){
//transforming code for array
$ra = $array[$a][0];
$na = str_replace(",", ",", $array[$a][1]);
$na = str_replace("\", "\\\\", $na);
$na = str_replace("'", "\'", $na);
$sc = $array[$a][2];
$kd = $array[$a][3];
$wi = $array[$a][4];
$ki = $array[$a][5];
$de = $array[$a][6];
$sh = $array[$a][7];
$ti = $array[$a][8];
$sp = $array[$a][9];
$sql .= "('$ra',' $na ','$sc','$kd','$wi','$ki','$de','$sh','$ti','$sp'),";
}
$sql = substr($sql, 0, -1);
$conn->query($sql);
}
$conn->close();
Right now it only inserts the first 5999 rows, but not more as if it only executed the loop once. No error messages..
Don't know if this'll necessarily help, but what about using array_chunk, array_walk, and checking error codes (if any)? Something like this:
function create_query(&$value, $key) {
//returns query statements; destructive though.
$value[1] = str_replace(",", ",", $value[1]);
$value[1] = str_replace("\", "\\\\", $value[1]);
$value[1] = str_replace("'", "\'", $value[1]);
$queryvalues = implode("','",$value);
$value = "INSERT INTO Ranking (rank, name, score, kd, wins, kills, deaths, shots, time, spree) VALUES ('".$queryvalues."');";
}
$array = array_chunk($arraysource, 6000);
foreach($array as $key=>$value){
array_walk($value,'create_query');
if (!$conn->query($value)) {
printf("Errorcode: %d\n", $conn->errno);
}
}
$conn->close();
Secondly, have you considered using mysqli::multi_query? It'll do more queries at once, but you'll have to check the max allowed packet size (max_allowed_packet).
Another tip would be to check out the response from the query, which your code doesn't include.
Thanks for the tips but I figured it out. Didn't think about this ^^
it was the first line after the for loop that i didnt include in my question:
array_unshift($array[$a], $a + 1);
this adds an additional value infront of each user, the "rank". But the numbers would repeat after one loop finishes and it can't import users with the same rank.
now it works:
array_unshift($array[$a], $a + 1 + $j * 5999);

different value of variable while inserting

I want to generate a pair of random numbers 1234567890-9876543210 (10 digits each)
I made this code. It works fine it generates a pair of random numbers BUT if I try to insert it into database I get same results multiple times. Let's say I get 1234567890 more than once. If I echo the insert statement I get different results but when I want to query it into database I get same results.
$numbers = array(0,1,2,3,4,5,6,7,8,9);
srand(time());
$f = fopen('sql0.txt', 'w');
for($i=0;$i<100000;$i++)
{
$r = NULL;
$r2 = NULL;
for($x=0;$x<10;$x++)
{
$n = rand(0,9);
$r .= $numbers[$n];
}
for($x=0;$x<10;$x++)
{
$n1 = rand(0,9);
$r2 .= $numbers[$n1];
}
echo("INSERT INTO ci_codes VALUES (NULL, '$r', '$r2', '0')<br>");
}
Do you need the INSERT expression inside your loop? That might cause the trouble.
As others have mentioned, it is better to just generate the numbers once with the php function, then run your MySql Query.
$r = mt_rand(0, 10000000);
$r2 = mt_rand(0, 10000000);
echo("INSERT INTO ci_codes VALUES (NULL, '$r', '$r2', '0'");

PHP Nested for loops

I basically want to scan a load of comments for illegal words and then replace those illegal words with a clean version.
I have two arrays, one array has all the comments to check, the other array has all of the illegal words to look for.
The first for loop gets the comments, the nested for loop then scans the comments for each of the illegal words and replaces them. The thing is though - it doesn't actually seem to work. Could you please advise if it is a problem with my loop structure, or the actual update logic?
$numComments = count($commentsToCheck);
$numIllegalWords = count($illegalWords);
for($i = 0; $i <= $numComments; $i++)
{
$message = $commentsToCheck[$i]['message'];
$commentId = $commentsToCheck[$i]['id'];
//error_log($message.'-'.$commentId);
for($j = 0; $j <= $numIllegalWords; $j++)
{
//Get word to replace with
$word = $illegalWords[$j]['word'];
//error_log($word);
$length = strlen($word);
$first = substr($word,0);
$last = substr($word,-1);
$starLength = $length - 2;
$replacement = $first.str_repeat('*',$starLength).$last;
$newMessage = preg_replace('/\b'.$word.'\b/i', $replacement, $message);
//Update the comment
$sql = "UPDATE ow_base_comment SET message = $newMessage WHERE id = $commentId LIMIT 1";
OW::getDbo()->query($sql);
}
}
Shouldnt your query not be what I placed below, since it wont see now the actual variables in the query. It will technincally just update nothing, cause there is no actual variable set.
$sql = "UPDATE ow_base_comment SET message = '".$newMessage."' WHERE id = '".$commentId."' LIMIT 1";
It's a common error to forget the quotes within PHP.

Categories