PHP/MySQL Limiting characters outputted from a field - php

When I get a database array, sometimes there is fields with too much data for my results list page, which is suppose to give just a short description. How do I limit the characters count to something like 100.
This is my array for the loop:
<?php
$i = 1;
while ($row = mysql_fetch_array($result)) {
?>
This is my echo statement:
<?php echo $row['description']; ?>

You can use substr like this:
<?php echo substr($row['description'], 0, 100); ?>
But it might be better—depending on your application needs—to do the limiting when making the initial MySQL query using SUBSTR which behaves the same way, but in MySQL.
SELECT SUBSTR(example_field, 1, 100)
FROM example_table
WHERE example_field IS NOT NULL
LIMIT 1
;
That MySQL script basically means return the substring of example_field starting from the first (1) character and going 100 characters in.
This might be better in some cases since if you are limiting text length to 100 characters, why grab the data for fields that might have 1,000+ characters? That would definitely bog down your PHP script in many cases. Handling that in MySQL is the best way to nip it in the bud if your app just needs 100 characters returned.

You can try with substr()
<?php echo substr($row['description'],0,100); ?>
OR
function truncate($input, $maxWords, $maxChars)
{
$words = preg_split('/\s+/', $input);
$words = array_slice($words, 0, $maxWords);
$words = array_reverse($words);
$chars = 0;
$truncated = array();
while(count($words) > 0)
{
$fragment = trim(array_pop($words));
$chars += strlen($fragment);
if($chars > $maxChars) break;
$truncated[] = $fragment;
}
$result = implode($truncated, ' ');
return $result . ($input == $result ? '' : '...');
}
// try with cuctom function truncate() , it help to cut description by words.
<?php echo truncate($row['description'],5,200); ?>

Like the other answers, you should use substr, but you can use it in combination with strpos so that when you shorten the string, you stop after a complete word instead of interrupting a word itself.
$pos = strpos($row['description'], ' ', 100);
echo substr($row['description'], $pos);

I would do it in the SQL query. It's better to limit the results returned which reduces I/O and network throughput by not returning data from the database you're not going to use. In your SQL query do:
SELECT LEFT(description, 100) AS description
,....
FROM ...

Just in case someone is interested in another code snippets on how to limit character output with dots, I use this and it works well for me
CONCAT(SUBSTR(<column_name_here>, 1, 100),'...... Read More') AS Column_Name

Related

Only allow the first 50-60 characters of a text field to be shown once posted [duplicate]

This question already has answers here:
Trim text to 340 chars [duplicate]
(9 answers)
Closed 7 years ago.
I only want the first 50 characters of '$output' that has been uploaded to the database to be shown on my page, what is the simplest way for me to do this? If the $output consists of more than 50 characters, I want the text to end on the last word it can without exceeding 50 characters and then put a "..." sort of thing, like a 'read more' section would.
PHP:
<?php
require_once("nbbc/nbbc.php");
$bbcode = new BBCode;
$sql = "SELECT * FROM posts ORDER BY id DESC";
$res = mysqli_query($dbCon, $sql) or die(mysqli_error($dbCon));
$posts = "";
if(mysqli_num_rows($res) > 0) {
while($row = mysqli_fetch_assoc($res)) {
$id = $row['id'];
$title = $row['title'];
$subtitle = $row['subtitle'];
$content = $row['content'];
$date = $row['date'];
$output = $bbcode->Parse($content);
$posts .= "<div id='post'><h2><a href='view_post.php?pid=$id' target='_blank'>$title</a></h2><h3 id='subtitle'>$subtitle</h3><h3 id='datethingy'><span style='color: #457F2C;'>Last updated:</span> $date</h3><p>$output</p></div>";
}
echo $posts;
}else {
echo "There are no posts to be displayed.";
}
?>
If your '$ouput' will be shown in a textfield like you said, the simplest way is:
<input type="text" maxlength="50">
The Simplest
You can just use substr to take the first 50 characters.
$output = substr($output, 0, 50);
The Most Efficient
If you're only going to display the first 50 characters, only query the database for the first 50 characters. This is much more efficient as you're transmitting less from the database.
// This is your SQL statement
SELECT LEFT(field, 50) AS excerpt FROM `table` WHERE ...
See this answer for more on only retrieving the first X characters from the database.
You can do something like this:
$str50 = substr($mystring, 0, 50);
thats the simplest way with pretty dots after the cut:
echo (strlen($var) > $length ? substr($var, 0, $length).'...' : $var);
Use one of the following,
$trimmedOutput = substr($output, 0, 50);
First parameter is the string you'd like the substring from. The second parameter is where you'd like the substring to stay from in the original string and the last parameter is where it would like to stop.
If you'd like 60 characters then change the 50 to 60.
If you don't want to cut a word, the best solution is to use the wordwrap function, like this :
function tokenTruncate($string, $your_desired_width) {
$parts = preg_split('/([\s\n\r]+)/', $string, null, PREG_SPLIT_DELIM_CAPTURE);
$parts_count = count($parts);
$length = 0;
$last_part = 0;
for (; $last_part < $parts_count; ++$last_part) {
$length += strlen($parts[$last_part]);
if ($length > $your_desired_width) { break; }
}
return implode(array_slice($parts, 0, $last_part));
}
This will split the text into lines that do not exceed 60 characters each, then will pick the first line. Scenarios like when the text is shorter than 60 characters, or has a line break before that limit are also handled.

PHP preg_replace limit not working?

I have a file that contains several colors as hexadecimals (i.e. #000 or #ffffff) and I'm trying to replace each of them with #varN where N is a number that increments with each replacement done. I believed my code does that, but $count always returns 196 after doing the placement even though I put the limit to 1 so count should never goes past 1. This results an endless loop. Why isn't it the limit working and what I can do to get the desired output?
$list = file($filepath.$file, FILE_USE_INCLUDE_PATH);
$pattern = "/#((([a-f]|[A-F]|[0-9]){6})|(([a-f]|[A-F]|[0-9]){3}))/";
$replaceVar = "#var";
$replaceNum = 0;
$count = 1;
while($count != 0){ //never ends
$replacement = $replaceVar.$replaceNum;
$output = preg_replace($pattern,$replacement,$list,1,$count);
$replaceNum++;
echo $replaceNum." ".$count."\n"; //returns $replaceNum and 196
}
file_put_contents($filepath.'/new'.$file,$output,FILE_USE_INCLUDE_PATH);
Example input file:
#000000
#111111
#123456
#abcdef
#123
#abc
Example output file:
#var1
#var2
#var3
#var4
#var5
#var6
You don't use the good function to do that for several reasons, I suggest you to use preg_replace_callback instead. Example:
$source = file_get_contents($yourfile);
$pattern = '~#[[:xdigit:]]{3}(?:[[:xdigit:]]{3})?~';
$count = 0;
$output = preg_replace_callback($pattern,
function ($m) use (&$count) { return '#var' . ++$count; },
$source);
You are always replacing on $list, but writing the result of the replacement to $output:
$output = preg_replace($pattern,$replacement,$list,1,$count);
This means, your $list will ALWAYS contain 1 match, when it starts with 1 - its never modified. Therefore your while will run without an end. You have to REPLACE it inside the same string you are scanning for more hits:
$list = preg_replace($pattern,$replacement,$list,1,$count);
now - at one point - $count should become zero, and $list contain no more unwanted matches.

Improve search result by broadening matches

I am trying to improve search result using PHP. e.g. when product name is ZSX-3185BC user can not find the product when put something like ZSX3185BC. So far i get something like:
$input = '01.10-2010';
$to_replace = array('.','-');
$clean = str_replace($to_replace, '/',$input);`
I've tried this, but it does not work correctly (not sure, posted in comment without elaboration -ed)
$str = "";
$len = strlen($strSearch) - 1;
// Loop through the search string to check each charecter is acceptable and strip those that are not
for ($i = 0; $i <= $len; $i++) {
if(preg_match("/\w|-| /",$strSearch[$i])) {
$str = $str . $strSearch[$i];
}
}
You should try to do this kind of fuzzy matching directly in your database query. A common approach to fuzzy string matching is the Levenshtein distance.
MySQL does not have this built in, however, it can be added. See this SO question.
The basic way is to add a stored function to MySQL. There is a Levenshtein implementation as a stored function.
Try this :
SELECT * FROM tablename WHERE replace(fieldname, '-', '') like '%ZSX3185BC%';

error using compare code

If i've database my_table (id,word) as following
and i've some posted text called $name then i want to know if $name have any word like words i've stored in my database my_table (id,word)
so i'm using this code
$name = "Hello lovely world"; // no bad words
$sql = "SELECT * FROM my_table";
$result = mysql_query($sql);
$commentArray = explode(" ", $name);
$counter = count($commentArray);
$check = 0;
while ($row = mysql_fetch_assoc($result)) {
for ($i == 0; $i < $counter; $i++) {
if (strcasecmp($commentArray[$i], $row['word'])) {
$check = 1;
}
}
}
if ($check == 1) {
echo "banned";
exit;
}
else {
echo "passed";
}
however it always results in echo "banned"; even if i $name is clear of any bad words i've stored in my_table so there might be something wrong here !
anyhelp
strcasecmp returns 0 when it matches (PHP manual), so you should edit your code:
if (strcasecmp($commentArray[$i], $row['word']) == 0)
Furthermore, you have a syntax error in your for loop. It should be for ($i = 0; ...
You have a syntax error.
for ($i = 0...
And not
for ($i == 0...
Also, you should indent your code properly, it looks better and it'll help you later on.
The thing is strcasecmp returns 0 if the strings are equal. You ought to change it to if (strcasecmp($var1, $var2) == 0).
As a starting point, I'd suggest storing only lowercased words in the table, lowercasing the input text first, and then replacing the whole strcasecmp loop with an in_array($row['word'], $commentArray);. And break; after the first match.
But this entire approach doesn't scale - you're selecting all the entries in the table. If your table grows beyond a certain size, that will be a serious bottleneck and you'll need to look into matching on the DB side.

PHP code for generating decent-looking coupon codes (mix of letters and numbers)

For an ecommerce site I want to generate a random coupon code that looks better than a randomly generated value. It should be a readable coupon code, all in uppercase with no special characters, only letters (A-Z) and numbers (0-9).
Since people might be reading this out / printing it elsewhere, we need to make this a simple-to-communicate value as well, perhaps 8-10 characters long.
Something like perhaps,
AHS3DJ6BW
B83JS1HSK
(I typed that, so it's not really that random)
$chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$res = "";
for ($i = 0; $i < 10; $i++) {
$res .= $chars[mt_rand(0, strlen($chars)-1)];
}
You can optimize this by preallocating the $res string and caching the result of strlen($chars)-1. This is left as an exercise to the reader, since probably you won't be generating thousands of coupons per second.
Try this:
substr(base_convert(sha1(uniqid(mt_rand())), 16, 36), 0, 10)
Why don't keep it simple?
<?php
echo strtoupper(uniqid());
?>
Always returns 13 character long uppercased random code.
You can use the coupon code generator PHP class file to generate N number of coupons and its customizable, with various options of adding own mask with own prefix and suffix. Simple PHP coupon code generator
Example:
coupon::generate(8); // J5BST6NQ
http://webarto.com/35/php-random-string-generator
Here you go.
function randr($j = 8){
$string = "";
for($i=0;$i < $j;$i++){
srand((double)microtime()*1234567);
$x = mt_rand(0,2);
switch($x){
case 0:$string.= chr(mt_rand(97,122));break;
case 1:$string.= chr(mt_rand(65,90));break;
case 2:$string.= chr(mt_rand(48,57));break;
}
}
return strtoupper($string); //to uppercase
}
If there are no security requirements for these, then you don't really need randomly generated codes. I would just use incremental IDs, such as those generated by whatever RDBMS you use. Optionally, if you have different types of coupons, you could prefix the codes with something, e.g.:
CX00019 QZ0001C
CX0001A QZ0001D
CX0001B QZ0001E
Alternately, you could even use dictionary words in the coupon, as such coupon codes are easier to remember and faster for users to type. Companies like Dreamhost use these for their promo codes, e.g.:
Promo60
NoSetupFee
YELLOWGORILLA82
Some of these are obviously human-created (which you might want to have the option of), but they can also be generated using a dictionary list. But even if they are randomly-generated nonsense phrases, the fact that the characters follow a logical pattern still makes it much more user-friendly than something like R7QZ8A92F1. So I would strongly advise against using the latter type of coupon codes just on the basis that they "look cool". Your customers will thank you.
$size = 12;
$string = strtoupper(substr(md5(time().rand(10000,99999)), 0, $size));
function generateCouponCode($length = 8) {
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$ret = '';
for($i = 0; $i < $length; ++$i) {
$random = str_shuffle($chars);
$ret .= $random[0];
}
return $ret;
}
you can find a lot of function in php rand manual
http://php.net/manual/en/function.rand.php
i like this one
<?php
//To Pull 8 Unique Random Values Out Of AlphaNumeric
//removed number 0, capital o, number 1 and small L
//Total: keys = 32, elements = 33
$characters = array(
"A","B","C","D","E","F","G","H","J","K","L","M",
"N","P","Q","R","S","T","U","V","W","X","Y","Z",
"1","2","3","4","5","6","7","8","9");
//make an "empty container" or array for our keys
$keys = array();
//first count of $keys is empty so "1", remaining count is 1-7 = total 8 times
while(count($keys) < 8) {
//"0" because we use this to FIND ARRAY KEYS which has a 0 value
//"-1" because were only concerned of number of keys which is 32 not 33
//count($characters) = 33
$x = mt_rand(0, count($characters)-1);
if(!in_array($x, $keys)) {
$keys[] = $x;
}
}
foreach($keys as $key){
$random_chars .= $characters[$key];
}
echo $random_chars;
?>
$length = 9;
$code = (strtoupper(substr(md5(time()), 0, $length)));
Just Write
$voucher_no = date('ymd') . rand(1000, 9999);
while(SapItem::where('voucher_no', $voucher_no)->exists()){
$voucher_no = date('ymd') . rand(1000, 9999);
}
Output: 2204171447

Categories