Insert Every Result of Foreach Loop into MySQL - php

Thanks for reading. I'm trying to parse an array of urls from Amazon, gather 4 variables ($name, $price, $stars, $reviews) and store the value of each of these into MySQL for every iteration in the Foreach Loop
The problem that I'm having is that only the information from the first url is being stored in MySQL (as you can see from the array I have 4 sites I'm trying to test this on.
I know that the code to get the correct values of the variables and such is correct because again this works for the first site, just doesn't go through the rest and I can't figure out why.
Any help would be greatly appreciated. Thanks!
function getSQL()
{
include('simple_html_dom.php');
$urlArray = array("http://www.amazon.com/kindle-fire-hdx-student-gaming-tablet/dp/B00BWYQ9YE/ref=sr_1_1?ie=UTF8&qid=1403276865&sr=8-1&keywords=kindle+fire+hdx", "http://www.amazon.com/Kindle-Fire-HDX-Display-Wi-Fi/dp/B00CUTT4HY/ref=sr_1_2?ie=UTF8&qid=1403276882&sr=8-2&keywords=kindle+fire+hdx",
"http://www.amazon.com/Kindle-Fire-HDX-Display-Wi-Fi/dp/B00BWYRF7E/ref=sr_1_3?ie=UTF8&qid=1403276882&sr=8-3&keywords=kindle+fire+hdx", "http://www.amazon.com/kindle-fire-hdx-best-movie-tablet-8.9/dp/B00BHJRYYS/ref=sr_1_5?ie=UTF8&qid=1403276882&sr=8-5&keywords=kindle+fire+hdx");
foreach ($testArray as $url)
{
$html = file_get_html("$url");
$name = $html->find('h1[class="parseasinTitle"]', 0)->plaintext; //line 6455
$price = $html->find('b[class=priceLarge]', 0)->plaintext; //line 6650
$string = $html->plaintext;
$wordToFind = 'stars';
$numWordsToWrap = 4;
$words = preg_split('/\s+/', $string);
if (($pos = array_search($wordToFind, $words)) !== FALSE) {
$start = ($pos - $numWordsToWrap > 0) ? $pos - $numWordsToWrap : 0;
$length = (($pos + ($numWordsToWrap + 1) < count($words)) ? $pos + 1 : count($words) - 1) - $start;
$slice = array_slice($words, $start, $length);
$stars = implode(' ', $slice);
} else echo 'I didn\'t find it';
$wordToFind2 = 'reviews';
$numWordsToWrap2 = 4;
$words2 = preg_split('/\s+/', $string);
if (($pos2 = array_search($wordToFind2, $words2)) !== FALSE) {
$start2 = ($pos2 - $numWordsToWrap2 > 0) ? $pos2 + 1 : 0;
$length2 = (($pos2 + ($numWordsToWrap2 + 1) < count($words2)) ? $pos2 + ($numWordsToWrap2 + 1) : count($words2) - 1) - $start2;
$slice2 = array_slice($words2, $start2, $length2);
$reviews = implode(' ', $slice2);
$reviews = str_replace(" ", "", $reviews);
} else echo 'I didn\'t find it';
$amazon_all_sql = "
insert into kindlefire
values('$name', '$price', '$stars', '$reviews');
";
return $amazon_all_sql;
}
}

You need to replace the following line
return $amazon_all_sql;
The foreach loop does the 1st round and then encounters the return statement. This terminates all processing in your function. Remove it and replace it with a statement that executes your sql.
If you just want to see all of the SQL that gets generated, change the following line and then pull the return outside of the foreach loop. (Note the .= operator used to append all the SQL to the $amazon_all_sql variable)
$amazon_all_sql .= "
insert into kindlefire
values('$name', '$price', '$stars', '$reviews');
";
}
return $amazon_all_sql;

Fix your return and your array name.
function getSQL()
{
include('simple_html_dom.php');
$urlArray = array("http://rads.stackoverflow.com/amzn/click/B00BWYQ9YE", "http://rads.stackoverflow.com/amzn/click/B00CUTT4HY",
"http://rads.stackoverflow.com/amzn/click/B00BWYRF7E", "http://rads.stackoverflow.com/amzn/click/B00BHJRYYS");
foreach ($urlArray as $url)
{
$html = file_get_html("$url");
$name = $html->find('h1[class="parseasinTitle"]', 0)->plaintext; //line 6455
$price = $html->find('b[class=priceLarge]', 0)->plaintext; //line 6650
$string = $html->plaintext;
$wordToFind = 'stars';
$numWordsToWrap = 4;
$words = preg_split('/\s+/', $string);
if (($pos = array_search($wordToFind, $words)) !== FALSE) {
$start = ($pos - $numWordsToWrap > 0) ? $pos - $numWordsToWrap : 0;
$length = (($pos + ($numWordsToWrap + 1) < count($words)) ? $pos + 1 : count($words) - 1) - $start;
$slice = array_slice($words, $start, $length);
$stars = implode(' ', $slice);
} else echo 'I didn\'t find it';
$wordToFind2 = 'reviews';
$numWordsToWrap2 = 4;
$words2 = preg_split('/\s+/', $string);
if (($pos2 = array_search($wordToFind2, $words2)) !== FALSE) {
$start2 = ($pos2 - $numWordsToWrap2 > 0) ? $pos2 + 1 : 0;
$length2 = (($pos2 + ($numWordsToWrap2 + 1) < count($words2)) ? $pos2 + ($numWordsToWrap2 + 1) : count($words2) - 1) - $start2;
$slice2 = array_slice($words2, $start2, $length2);
$reviews = implode(' ', $slice2);
$reviews = str_replace(" ", "", $reviews);
} else echo 'I didn\'t find it';
$amazon_all_sql = "
insert into kindlefire
values('$name', '$price', '$stars', '$reviews');
";
}
return $amazon_all_sql;
}

Related

how to reverse two Characters of string? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I want to reverse two characters of string in PHP. For example 50378f to 8f3750 please help me.
$str= User::where('id',$userid)->pluck('card_id');
$num = strrev($number);
echo $num;
This function is reversing very good but I want to reverse two characters not one character.
My function is giving me output example: 12345 to 543210 but I want it like
103254.
You can try this:
$originalString = '23242526';
$arrayWith2CharsPerElement = str_split($originalString, 2);
$arrayWithReversedKeys = array_reverse($arrayWith2CharsPerElement);
$newStringInReverseOrder = implode($arrayWithReversedKeys);
echo $newStringInReverseOrder; //will print 26252423
Edit: changed the approach to work with odd strings
$string = '121314152';
$countDown = strlen($string);
$substrLength = 2;
$reverseString = '';
while ($countDown > 0) {
$startPosition = $countDown -2;
if ($countDown == 1) {
$startPosition = 0;
$substrLength = 1;
}
$reverseString .= substr($string, $startPosition, $substrLength);
$countDown -= 2;
}
echo $reverseString; //will print 524131211
You can try
function strReverse($string) {
$newString = "";
if ((strlen($string) % 2) != 0) $string = "0". $string;
for($pos = 0; $pos < strlen($string); $pos++) {
$chr = substr($string, $pos, 1);
if (($pos % 2) == 0) {
$tmp = $chr;
} else {
$newString .= $chr . $tmp;
$tmp = "";
}
}
if ($tmp != "") $newString .= $tmp;
return $newString;
}
echo strReverse('12345'); // result 103254
I have rewrite the function, you can define how many length of character you want to reverse by modify $noOfChar.
Example, if you set $noOfChar = 3, 12345 result will be 1004325.
function strReverse($string) {
$newString = "";
$noOfChar = 2;
$remain = strlen($string) % $noOfChar;
$string = str_repeat("0", $remain) . $string;
$segment = "";
for($pos = 0; $pos < strlen($string); $pos++) {
$segment = $segment . substr($string, $pos, 1);
if ((($pos + 1) % $noOfChar) == 0) {
$newString .= strrev($segment);
$segment = "";
}
}
if ($segment != "") $newString .= strrev($segment);
return $newString;
}
echo strReverse('12345');
You can use below function for reverse string by two slot.
function reverseByTwoCharacters($string)
{
$stringReversed = "";
if (!empty($string)) {
$stringLength = strlen($string);
if ($stringLength % 2 == 0) {
$splittedString = str_split($string, 2);
} else {
$splittedString = str_split(substr($string, 1), 2);
array_unshift($splittedString, $string[0]);
}
$reverseString = array_reverse($splittedString);
$stringReversed = implode($reverseString);
}
return $stringReversed;
}
$string = "1234567890";
echo reverseByTwoCharacters($string);
// Output
9078563412

PHP: Get string between two character with specific index

I am a beginner of PHP. I have string:
$fullstring = "this is [tag]dog[/tag], [tag]cat[/tag], [tag]lion[/tag]";
I want to get string "cat" from my $fullstring.
I used to try with this:
Get substring between two strings PHP
But I can only get the first string (dog). Thank you for your time.
Thet Cartter.
Disclaimer: Both solution is naive. You should always check the returned value of preg_match_all and strpos.
Readable regex solution:
Try to use preg_match_all
$fullstring = "this is [tag]dog[/tag], [tag]cat[/tag], [tag]lion[/tag]";
preg_match_all("'\[tag\](.*?)\[\/tag\]'si", $fullstring, $match);
foreach($match[1] as $val){
echo $val, ' ';
}
// result: dog cat lion
To get only the content of the second tag (which is cat now)
echo $match[1][1]
// result: cat
Not readable string split solution:
$fullstring = 'this is [tag]dog[/tag], [tag]cat[/tag], [tag]lion[/tag]';
function get_strings_between(string $string, string $start, string $end): array {
$r = [];
$startLen = strlen($start);
$endLen = strlen($end);
while (!empty($string)) {
$startPosition = strpos($string, $start);
if ($startPosition === false) {
return $r;
}
$contentStart = $startPosition + $startLen;
$contentEnd = strpos($string, $end, $contentStart);
$len = $contentEnd - $contentStart;
$r[] = substr($string, $contentStart, $len);
$endPosition = $contentEnd + $endLen;
$string = substr($string, $endPosition);
}
return $r;
}
$match = get_strings_between($fullstring, '[tag]', '[/tag]');
// result: dog cat lion
To get only the content of the second tag (which is cat now)
echo $match[1]
// result: cat
This is a modified version of this answer. This function will return all instances it can find based on what you want to search.
function getContents($str, $startDelimiter, $endDelimiter, $needle) {
$contents = array();
$startDelimiterLength = strlen($startDelimiter);
$endDelimiterLength = strlen($endDelimiter);
$startFrom = $contentStart = $contentEnd = 0;
while (false !== ($contentStart = strpos($str, $startDelimiter, $startFrom))) {
$contentStart += $startDelimiterLength;
$contentEnd = strpos($str, $endDelimiter, $contentStart);
if (false === $contentEnd) {
break;
}
$tempString = substr($str, $contentStart, $contentEnd - $contentStart);
if ($tempString == $needle) {
$contents[] = $tempString;
}
$startFrom = $contentEnd + $endDelimiterLength;
}
return $contents;
}
You're looking for preg_match() function. An example below may help you out.
$fullString = "this is [tag]dog[/tag], [tag]cat[/tag], [tag]lion[/tag]";
$regex = "/\[tag\]\w+\[\\tag\]/";
preg_match($regex, $fullString, $matches);
foreach($matches as $match){
echo $match;
}
// result, dog, cat, lion
I try to modify the old function [http://www.justin-cook.com/wp/2006/03/31/php-parse-a-string-between-two-strings/]. I got this:
function get_string_between($string, $start, $end, $index){
if ($index <= 0) return '';
$string = ' ' . $string;
$ini = 0;
$x = 1;
while ($x <= $index) {
$ini = strpos($string, $start, $ini + 1);
if ($ini == 0) return '';
$x++;
}
$ini += strlen($start);
$len = strpos($string, $end, $ini) - $ini;
return substr($string, $ini, $len);
}
$fullstring = "this is [tag]dog[/tag], [tag]cat[/tag], [tag]lion[/tag]";
echo get_string_between($fullstring, "[tag]", "[/tag]", 2); // Result = cat

String reverse in another way

I'm searching for a function which can reverse a string in another way.
it should always takes the last and the first char of the string.
In example the string
123456
should become
615243
Is there any php function?
EDIT
This is my code so far
$mystring = "1234";
$start = 0;
$end = strlen($mystring);
$direction = 1;
$new_str = '';
while ($start === $end) {
if ($direction == 0) {
$new_str .= substr($mystring, $start, 1);
$start++;
$direction = 1;
} else {
$new_str .= substr($mystring, $end, -1);
$end--;
$direction = 0;
}
}
I couldn't help myself, I just had to write your code for you...
This just takes your string, splits it into an array, then builds up your output string taking letters from the front and end.
$output = '';
$input = str_split('123456');
$length = count($input);
while(strlen($output) < $length) {
$currLength = strlen($output);
if($currLength % 2 === 1) {
$output .= array_shift($input);
}
else {
$output .= array_pop($input);
}
}
echo $output;
Example: http://ideone.com/Xyd0z6
Not very different from Scopey's answer with a for loop:
$str = '123456';
$result = '';
$arr = str_split($str);
for ($i=0; $arr; $i++) {
$result .= $i % 2 ? array_shift($arr) : array_pop($arr);
}
echo $result;
This should work for you:
<?php
$str = "123456";
$rev = "";
$first = substr($str, 0, strlen($str)/2);
$last = strrev(substr($str, strlen($str)/2));
$max = strlen($first) > strlen($last) ? strlen($first): strlen($last);
for($count = 0; $count < $max; $count++)
$rev .= (isset($last[$count])?$last[$count]:"" ) . (isset($first[$count])?$first[$count]: "");
echo $rev;
?>
Output:
615243

PHP usort - array indexes not moving correctly

I'm trying to order string based on a custom alphabet. I have php code that breaks the file to be sorted into an array of strings. I'm attempting to order each string. The strings are ordering themselves correctly, but they aren't moving around the array correctly. I'm new to php, so I'm hoping someone could show me my errors.
Thanks :)
<?php
echo " start ";
$file = fopen('inFile.txt', "r");
$firstLine = fgets($file);
echo " hi ";
$x = 0;
while(! feof($file)){
$restOfFile[$x] = fgets($file);
$x++;
}
$firstLine = str_replace(' ','',$firstLine);
fclose($file);
//echo $firstLine;
//print_r( $restOfFile);
function mylst($a,$b){
$pos1 = 0;
$pos2 = 0;
global $firstLine;
if(strlen($a) > strlen($b)){
$string = $b;
}else{
$string = $a;
}
for ($i=0;$i<(strlen($string) && $pos1===$pos2); $i++){
$pos1 = strpos($firstLine,substr($a,1));
$pos2 = strpos($firstLine,substr($b,1));
}
if ($pos1 === $pos2 && strlen($a) !== strlen($b)){
return (strlen($a)-strlen($b));
}
return $pos1-$pos2;
}
echo " BEFORE ";
print_r($restOfFile);
echo " AFTER ";
usort($restOfFile,"mylst");
print_r($restOfFile);
?>
The main problem I think is the substr() usage.
substr($b,1)
Returns everything from the first position to the end of the string. It should be:
substr($b, $i, 1)
Modified function:
function mylst($a,$b){
$pos1 = 0;
$pos2 = 0;
global $firstLine;
$l = (strlen($a) > strlen($b)) ? strlen($b) : strlen($a);
for ( $i = 0; ($i < $l) && ($pos1 === $pos2); $i++){
$pos1 = strpos($firstLine,substr($a,$i,1));
$pos2 = strpos($firstLine,substr($b,$i,1));
}
if ($pos1 === $pos2 && strlen($a) !== strlen($b)){
return (strlen($a)-strlen($b));
}
return $pos1-$pos2;
}

keyword highlight is highlighting the highlights in PHP preg_replace()

I have a small search engine doing its thing, and want to highlight the results. I thought I had it all worked out till a set of keywords I used today blew it out of the water.
The issue is that preg_replace() is looping through the replacements, and later replacements are replacing the text I inserted into previous ones. Confused? Here is my pseudo function:
public function highlightKeywords ($data, $keywords = array()) {
$find = array();
$replace = array();
$begin = "<span class=\"keywordHighlight\">";
$end = "</span>";
foreach ($keywords as $kw) {
$find[] = '/' . str_replace("/", "\/", $kw) . '/iu';
$replace[] = $begin . "\$0" . $end;
}
return preg_replace($find, $replace, $data);
}
OK, so it works when searching for "fred" and "dagg" but sadly, when searching for "class" and "lass" and "as" it strikes a real issue when highlighting "Joseph's Class Group"
Joseph's <span class="keywordHighlight">Cl</span><span <span c<span <span class="keywordHighlight">cl</span>ass="keywordHighlight">lass</span>="keywordHighlight">c<span <span class="keywordHighlight">cl</span>ass="keywordHighlight">lass</span></span>="keywordHighlight">ass</span> Group
How would I get the latter replacements to only work on the non-HTML components, but to also allow the tagging of the whole match? e.g. if I was searching for "cla" and "lass" I would want "class" to be highlighted in full as both the search terms are in it, even though they overlap, and the highlighting that was applied to the first match has "class" in it, but that shouldn't be highlighted.
Sigh.
I would rather use a PHP solution than a jQuery (or any client-side) one.
Note: I have tried to sort the keywords by length, doing the long ones first, but that means the cross-over searches do not highlight, meaning with "cla" and "lass" only part of the word "class" would highlight, and it still murdered the replacement tags :(
EDIT: I have messed about, starting with pencil & paper, and wild ramblings, and come up with some very unglamorous code to solve this issue. It's not great, so suggestions to trim/speed this up would still be greatly appreciated :)
public function highlightKeywords ($data, $keywords = array()) {
$find = array();
$replace = array();
$begin = "<span class=\"keywordHighlight\">";
$end = "</span>";
$hits = array();
foreach ($keywords as $kw) {
$offset = 0;
while (($pos = stripos($data, $kw, $offset)) !== false) {
$hits[] = array($pos, $pos + strlen($kw));
$offset = $pos + 1;
}
}
if ($hits) {
usort($hits, function($a, $b) {
if ($a[0] == $b[0]) {
return 0;
}
return ($a[0] < $b[0]) ? -1 : 1;
});
$thisthat = array(0 => $begin, 1 => $end);
for ($i = 0; $i < count($hits); $i++) {
foreach ($thisthat as $key => $val) {
$pos = $hits[$i][$key];
$data = substr($data, 0, $pos) . $val . substr($data, $pos);
for ($j = 0; $j < count($hits); $j++) {
if ($hits[$j][0] >= $pos) {
$hits[$j][0] += strlen($val);
}
if ($hits[$j][1] >= $pos) {
$hits[$j][1] += strlen($val);
}
}
}
}
}
return $data;
}
I've used the following to address this problem:
<?php
$protected_matches = array();
function protect(&$matches) {
global $protected_matches;
return "\0" . array_push($protected_matches, $matches[0]) . "\0";
}
function restore(&$matches) {
global $protected_matches;
return '<span class="keywordHighlight">' .
$protected_matches[$matches[1] - 1] . '</span>';
}
preg_replace_callback('/\x0(\d+)\x0/', 'restore',
preg_replace_callback($patterns, 'protect', $target_string));
The first preg_replace_callback pulls out all matches and replaces them with nul-byte-wrapped placeholders; the second pass replaces them with the span tags.
Edit: Forgot to mention that $patterns was sorted by string length, longest to shortest.
Edit; another solution
<?php
function highlightKeywords($data, $keywords = array(),
$prefix = '<span class="hilite">', $suffix = '</span>') {
$datacopy = strtolower($data);
$keywords = array_map('strtolower', $keywords);
$start = array();
$end = array();
foreach ($keywords as $keyword) {
$offset = 0;
$length = strlen($keyword);
while (($pos = strpos($datacopy, $keyword, $offset)) !== false) {
$start[] = $pos;
$end[] = $offset = $pos + $length;
}
}
if (!count($start)) return $data;
sort($start);
sort($end);
// Merge and sort start/end using negative values to identify endpoints
$zipper = array();
$i = 0;
$n = count($end);
while ($i < $n)
$zipper[] = count($start) && $start[0] <= $end[$i]
? array_shift($start)
: -$end[$i++];
// EXAMPLE:
// [ 9, 10, -14, -14, 81, 82, 86, -86, -86, -90, 99, -103 ]
// take 9, discard 10, take -14, take -14, create pair,
// take 81, discard 82, discard 86, take -86, take -86, take -90, create pair
// take 99, take -103, create pair
// result: [9,14], [81,90], [99,103]
// Generate non-overlapping start/end pairs
$a = array_shift($zipper);
$z = $x = null;
while ($x = array_shift($zipper)) {
if ($x < 0)
$z = $x;
else if ($z) {
$spans[] = array($a, -$z);
$a = $x;
$z = null;
}
}
$spans[] = array($a, -$z);
// Insert the prefix/suffix in the start/end locations
$n = count($spans);
while ($n--)
$data = substr($data, 0, $spans[$n][0])
. $prefix
. substr($data, $spans[$n][0], $spans[$n][1] - $spans[$n][0])
. $suffix
. substr($data, $spans[$n][1]);
return $data;
}
I had to revisit this subject myself today and wrote a better version of the above. I'll include it here. It's the same idea only easier to read and should perform better since it uses arrays instead of concatenation.
<?php
function highlight_range_sort($a, $b) {
$A = abs($a);
$B = abs($b);
if ($A == $B)
return $a < $b ? 1 : 0;
else
return $A < $B ? -1 : 1;
}
function highlightKeywords($data, $keywords = array(),
$prefix = '<span class="highlight">', $suffix = '</span>') {
$datacopy = strtolower($data);
$keywords = array_map('strtolower', $keywords);
// this will contain offset ranges to be highlighted
// positive offset indicates start
// negative offset indicates end
$ranges = array();
// find start/end offsets for each keyword
foreach ($keywords as $keyword) {
$offset = 0;
$length = strlen($keyword);
while (($pos = strpos($datacopy, $keyword, $offset)) !== false) {
$ranges[] = $pos;
$ranges[] = -($offset = $pos + $length);
}
}
if (!count($ranges))
return $data;
// sort offsets by abs(), positive
usort($ranges, 'highlight_range_sort');
// combine overlapping ranges by keeping lesser
// positive and negative numbers
$i = 0;
while ($i < count($ranges) - 1) {
if ($ranges[$i] < 0) {
if ($ranges[$i + 1] < 0)
array_splice($ranges, $i, 1);
else
$i++;
} else if ($ranges[$i + 1] < 0)
$i++;
else
array_splice($ranges, $i + 1, 1);
}
// create substrings
$ranges[] = strlen($data);
$substrings = array(substr($data, 0, $ranges[0]));
for ($i = 0, $n = count($ranges) - 1; $i < $n; $i += 2) {
// prefix + highlighted_text + suffix + regular_text
$substrings[] = $prefix;
$substrings[] = substr($data, $ranges[$i], -$ranges[$i + 1] - $ranges[$i]);
$substrings[] = $suffix;
$substrings[] = substr($data, -$ranges[$i + 1], $ranges[$i + 2] + $ranges[$i + 1]);
}
// join and return substrings
return implode('', $substrings);
}
// Example usage:
echo highlightKeywords("This is a test.\n", array("is"), '(', ')');
echo highlightKeywords("Classes are as hard as they say.\n", array("as", "class"), '(', ')');
// Output:
// Th(is) (is) a test.
// (Class)es are (as) hard (as) they say.
OP - something that's not clear in the question is whether $data can contain HTML from the get-go. Can you clarify this?
If $data can contain HTML itself, you are getting into the realms attempting to parse a non-regular language with a regular language parser, and that's not going to work out well.
In such a case, I would suggest loading the $data HTML into a PHP DOMDocument, getting hold of all of the textNodes and running one of the other perfectly good answers on the contents of each text block in turn.

Categories