-
-
Save balwantmeticulosity/2e471821838fd725c93abbcee583c23d to your computer and use it in GitHub Desktop.
| <?php | |
| /* | |
| 💬 Get Google-Reviews with PHP cURL & without API Key | |
| ===================================================== | |
| **This is a dirty but usefull way to grab the first 8 most relevant reviews from Google with cURL and without the use of an API Key** | |
| How to find the needed CID No: | |
| - use: [https://pleper.com/index.php?do=tools&sdo=cid_converter] | |
| - and do a search for your business name | |
| Parameter | |
| --------- | |
| ```PHP | |
| $options = array( | |
| 'google_maps_review_cid' => '17311646584374698221', // Customer Identification (CID) | |
| 'show_only_if_with_text' => false, // true = show only reviews that have text | |
| 'show_only_if_greater_x' => 0, // (0-4) only show reviews with more than x stars | |
| 'show_rule_after_review' => true, // false = don't show <hr> Tag after each review | |
| 'show_blank_star_till_5' => true, // false = don't show always 5 stars e.g. ⭐⭐⭐☆☆ | |
| 'your_language_for_tran' => 'en', // give you language for auto translate reviews | |
| 'sort_by_reating_best_1' => true, // true = sort by rating (best first) | |
| 'show_cname_as_headline' => true, // true = show customer name as headline | |
| 'show_age_of_the_review' => true, // true = show the age of each review | |
| 'show_txt_of_the_review' => true, // true = show the text of each review | |
| 'show_author_of_reviews' => true, // true = show the author of each review | |
| ); | |
| echo getReviews($options); | |
| ``` | |
| > HINT: Use .quote in you CSS to style the output | |
| ###### Copyright 2019-2020 Igor Gaffling | |
| */ | |
| $options = array( | |
| 'google_maps_review_cid' => '10054689419972994821', // Customer Identification (CID) | |
| 'show_only_if_with_text' => false, // true = show only reviews that have text | |
| 'show_only_if_greater_x' => 0, // (0-4) only show reviews with more than x stars | |
| 'show_rule_after_review' => true, // false = don't show <hr> Tag after each review (and before first) | |
| 'show_blank_star_till_5' => true, // false = don't show always 5 stars e.g. ⭐⭐⭐☆☆ | |
| 'your_language_for_tran' => 'en', // give you language for auto translate reviews | |
| 'sort_by_reating_best_1' => true, // true = sort by rating (best first) | |
| 'show_cname_as_headline' => true, // true = show customer name as headline | |
| 'show_age_of_the_review' => true, // true = show the age of each review | |
| 'show_txt_of_the_review' => true, // true = show the text of each review | |
| 'show_author_of_reviews' => true, // true = show the author of each review | |
| ); | |
| /* -------------------- */ | |
| echo getReviews($options); | |
| /* -------------------- */ | |
| function getReviews($option) { | |
| $ch = curl_init('https://www.google.com/maps?cid='.$option['google_maps_review_cid']); /* GOOGLE REVIEWS BY cURL */ | |
| if ( isset($option['your_language_for_tran']) and !empty($option['your_language_for_tran']) ) { | |
| curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept-Language: '.$option['your_language_for_tran'])); | |
| } | |
| curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36'); | |
| curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); | |
| curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); | |
| $result = curl_exec($ch); | |
| curl_close($ch); /* </cURL END> */ | |
| $pattern = '/window\.APP_INITIALIZATION_STATE(.*);window\.APP_FLAGS=/ms'; /* REVIEW REGEX PATTERN */ | |
| if ( preg_match($pattern, $result, $match) ) { /* CHECK IF REVIEWS FOUND */ | |
| $match[1] = trim($match[1], ' =;'); /* DIRTY JSON FIX */ | |
| $reviews = json_decode($match[1]); /* 2. JSON DECODE */ | |
| $reviews = ltrim($reviews[3][6], ")]}'"); /* DIRTY JSON FIX */ | |
| $reviews = json_decode($reviews); /* 2. JSON DECODE */ | |
| $customer = $reviews[6][11]; /* POSITION OF REVIEWS */ | |
| $reviews = $reviews[6][52][0]; /* POSITION OF REVIEWS */ | |
| } /* END CHECK */ | |
| $return = ''; /* INI VAR */ | |
| if (isset($reviews)) { /* CHECK REVIEWS */ | |
| if ( isset($option['sort_by_reating_best_1']) and $option['your_lansort_by_reating_best_1guage_for_tran'] == true ) /* CHECK SORT */ | |
| array_multisort(array_map(function($element) { return $element[4]; }, $reviews), SORT_DESC, $reviews); /* SORT */ | |
| $return .= '<div class="quote">'; /* OPEN DIV */ | |
| if (isset($option['show_cname_as_headline']) and $option['show_cname_as_headline'] == true) $return .= '<strong>'.$customer.'</strong><br>'; /* CUSTOMER */ | |
| if (isset($option['show_rule_after_review']) and $option['show_rule_after_review'] == true) $return .= '<hr size="1">'; /* RULER */ | |
| foreach ($reviews as $review) { /* START LOOP */ | |
| if (isset($option['show_only_if_with_text']) and $option['show_only_if_with_text'] == true and empty($review[3])) continue; /* CHECK TEXT */ | |
| if (isset($option['show_only_if_greater_x']) and $review[4] <= $option['show_only_if_greater_x']) continue; /* CHECK RATING */ | |
| for ($i=1; $i <= $review[4]; ++$i) $return .= '⭐'; /* RATING */ | |
| if (isset($option['show_blank_star_till_5']) and $option['show_blank_star_till_5'] == true) for ($i=1; $i <= 5-$review[4]; ++$i) $return .= '☆'; /* RATING */ | |
| $return .= '<br>'; /* NEWLINE */ | |
| if (isset($option['show_txt_of_the_review']) and $option['show_txt_of_the_review'] == true) $return .= $review[3].'<br>'; /* TEXT */ | |
| if (isset($option['show_age_of_the_review']) and $option['show_age_of_the_review'] == true) $return .= '<small>'.$review[0][1].' </small>'; /* AUTHOR */ | |
| if (isset($option['show_age_of_the_review']) and $option['show_age_of_the_review'] == true and /* IF AUTHOR & AGE */ | |
| isset($option['show_age_of_the_review']) and $option['show_age_of_the_review'] == true) $return .= '<small> — </small>'; /* PRINT — */ | |
| if (isset($option['show_age_of_the_review']) and $option['show_age_of_the_review'] == true) $return .= '<small>'.$review[1].' </small>'; /* AGE */ | |
| if (isset($option['show_rule_after_review']) and $option['show_rule_after_review'] == true) $return .= '<hr size="1">'; /* RULER */ | |
| } /* END LOOP */ | |
| $return .= '</div>'; /* CLOSE DIV */ | |
| } /* CHECK REVIEWS */ | |
| return $return; /* RETURN DATA */ | |
| } /* END OF FUNCTION */ |
Great script too bad it only works for a few days. How is that possible?
Google moved the URL. You have to put &ucbcb=1 after the CID.
Good !!!
how to filter from newest to oldest please?
Thanks
Indeed, it stopped working for me after a few days. Is there a specific reason?
yesterday my code also stopped working. Anyone know what is the reason for that?
@divz90 I was looking through the results array and it looks like its location (and the edit to line 74) is now:
$reviews = $reviews[6][175][9][0][0];
Hope that helps!
Thanks, @kakitzmiller ! before it was showing an empty page, not after your suggestion, it shows the name of the business (but nothing else, no reviews to be seen). Just reporting on my end. Do you get the reviews?
Anyone in Aug 2024
Looks like the returned array has completely changed location trying to work on fixing it, anyone else had any luck?
Anyone in Aug 2024 Looks like the returned array has completely changed location trying to work on fixing it, anyone else had any luck?
No luck sofar :( Keep us updated!
Hello, I have got it to work again
Have to first change:
//$customer = $reviews[0][1][0][14][18];
//$reviews = $reviews[0][1][0][14][52][0];
//$customer = $reviews[6][18]; // NEW IN 2020
//$reviews = $reviews[6][52][0]; // NEW IN 2020
$customer = $reviews[6][175][9]; // NEW IN 2024
$reviews = $reviews[6][175][9][0][0]; // NEW IN 2024
Then inside the loop also change these 3 lines:
$comment_name=$review[0][1][4][5][0]; // NEW IN 2024
$review_text=$review[0][2][15][0][0]; // NEW IN 2024
$comment_rating=$review[0][2][0][0]; // NEW IN 2024
Let me know if it works for you :)
Thanks for your help! It seems the changes aren’t working on my end—perhaps I’m not applying them correctly. Would it be possible to copy and paste the complete code here to ensure I’m inserting it correctly?
Thank you for ur replay. Its working for me also.
hello @cladreams, please copy and paste the complete code here
Hello, currently moving house so no access to computer but I'll upload next week
Thanks, buddy, I really appreciate it, since it's not working on my end.
Thanks @cladreams
cc @cladreams
My code in 2024
<?php
/*Get Google-Reviews with PHP cURL & without API Key
=====================================================
- use: [https://pleper.com/index.php?do=tools&sdo=cid_converter]
*/
$options = array(
'google_maps_review_cid' => 'YOUR-CID',
'show_only_if_with_text' => false,
'show_only_if_greater_x' => 0,
'show_rule_after_review' => true,
'show_blank_star_till_5' => true,
'your_language_for_tran' => 'pt-BR',
'sort_by_reating_best_1' => true,
'show_cname_as_headline' => true,
'show_age_of_the_review' => true,
'show_txt_of_the_review' => true,
'show_author_of_reviews' => true,
);
function getReviews($option, $CID = '')
{
if(isset($CID) && $CID !== ''){
$option['google_maps_review_cid'] = $CID;
}
$ch = curl_init('https://www.google.com/maps?cid=' . ($option['google_maps_review_cid']));
if (isset($option['your_language_for_tran']) and !empty($option['your_language_for_tran'])) {
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept-Language: ' . $option['your_language_for_tran']));
}
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
curl_close($ch);
$pattern = '/window\.APP_INITIALIZATION_STATE(.*);window\.APP_FLAGS=/ms';
if (preg_match($pattern, $result, $match)) {
$match[1] = trim($match[1], ' =;');
$reviews = json_decode($match[1]);
$reviews = ltrim($reviews[3][6], ")]}'");
$reviews = json_decode($reviews);
$customer = $reviews[6][11];
$reviews = $reviews[6][175][9][0][0];
}
$return = '';
if (isset($reviews)) {
if (isset($option['sort_by_reating_best_1'])) {
usort($reviews, function ($a, $b) {
// Replace 'date' with the exact path or index where the timestamp is stored in the review array
$dateA = strtotime($a[0][1][6]); // Example: change this path to match your structure
$dateB = strtotime($b[0][1][6]);
return $dateB <=> $dateA; // Sorts in descending order
});
$return .= '<div class="reviews">';
foreach ($reviews as $review) {
//$nome = $review[0][1][4][1][1]; //nao funciona mais
// print_r($review[0][1][4][5][0]);exit;
$nome = $review[0][1][4][5][0];
//$imagem = $review[0][1][4][1][2]; //nao funciona mais
// print_r($review[0][1][4][5][1]);exit;
$imagem = $review[0][1][4][5][1];
$estrelas = $review[0][2][0][0];
$descricao = isset($review[0][2][15][0][0]) ? resumirDescricao($review[0][2][15][0][0]) : 'Sem descrição';
$dataAvaliacao = $review[0][1][6];
// Exibição dos dados
$return .= '<div class="item border text-center mx-3 p-2 d-flex align-items-center flex-column justify-content-between" style="min-height:300px">';
$return .= "<img src=\"$imagem\" class=\"mb-2\" style=\"width:50px\"/>";
$return .= '<h3 class="fs-6">'.$nome.'</h3>';
$return .= '<div class="my-3">' . str_repeat('⭐', $estrelas) . str_repeat('☆', 5 - $estrelas) . '</div>';
$return .= "<p class=\"fs-6\"><small>$descricao</small></p>";
$return .= "<small class=\"bg-light border p-1 rounded-pill px-4\" style=\"font-size:12px;\">$dataAvaliacao</small>";
$return .= '</div>';
}
}
$return .= '</div>';
}
return $return;
}
function resumirDescricao($descricao, $limitePalavras = 10) {
$palavras = explode(' ', $descricao);
if (count($palavras) > $limitePalavras) {
$descricaoCurtada = implode(' ', array_slice($palavras, 0, $limitePalavras)) . '...';
} else {
$descricaoCurtada = $descricao;
}
return $descricaoCurtada;
}
?>
Any suggestions for ordering the comments, returning the newest to the oldest. this doesn't work in my current code.
in 2025 the url return "302 Moved"
Hi dear!
How can I ignore auto translate?
how can I get more reviews by date and earlies!
thanks
TY