The code:
$row['text'] = 'http://t.co/iBSiZZD4 and http://t.co/1rG3oNmc and http://t.co/HGFjwqHI and http://t.co/8UldEAVt';
if(preg_match_all('|http:\/\/t.co\/.{1,8}|i',$row['text'],$matches)){
foreach($matches[0] as $value){
$headers = get_headers($value,1);
if(is_array($headers['Location'])){
$headers['Location'] = $headers['Location'][0];
}
$row['text'] = preg_replace('|http:\/\/t.co\/.{1,8}|i', '' . $headers['Location'] . '',$row['text']);
}
}
This is related to get_headers(). Sometimes get_headers($url,1) returns an array with a location index key like so: [Location]=>Array([0]=>url1 [1]=>url2). I basically want to make [Location] equal to [Location][0] if [Location][0] exists. However, the above code doesn't seem to accomplish that task. I've also tried array_key_exists() and isset() but neither solved the problem. Thoughts?
Don't try to replace on the fly. First get all the values, and then do the replace in one batch (using two arrays as the $search and $replace parameters).
<?php
$replace = array();
$row = array('text' => 'http://t.co/iBSiZZD4 and http://t.co/1rG3oNmc and http://t.co/HGFjwqHI and http://t.co/8UldEAVt');
if (preg_match_all('|http:\/\/t.co\/.{1,8}|i', $row['text'], $search)) {
foreach ($search[0] as $value) {
$headers = get_headers($value, 1);
if (is_array($headers['Location'])) {
$headers['Location'] = $headers['Location'][0];
}
$replace[] = "<a href='{$headers["Location"]}'>{$headers["Location"]}</a>";
}
$row['text'] = str_replace($search[0], $replace, $row['text']);
echo $row["text"];
}
P.S. - Next time, please tell us the context of your problem, tell us you "are making a service that resolves shortened URLs", don't let me figure that out from your code alone.
Related
I am trying to create pdf from the values of a dynamic form.
I am collecting and storing dynamic inputs like this.
$inputarray = array();
foreach ($_POST['input'] as $input) {
$inputarray[] = $input;
}
Now I want to replace a template with the values collected from the form. My current codes look like this.
//count total number of inputs
$icount = count($_POST['input']);
//replace template with values
ob_start();
$require_once 'template.php';
$html = ob_get_clean();
$template = str_replace(array('%name%', '%input0%', '%input1%', '%input2%'), array($name, $inputarray[0], $inputarray[1], $inputarray[2]), $html);
The code of my template.php looks like this.
<tr><td>%name%</td></tr>
<?php
for ($i=0; $i<$icount; $i++){
echo '<tr>';
echo '<td>%input'.$i.'%</td>';
echo '</tr>';
?>
My code is working fine if I use %input1%, %input2% manually. My question is how do I automate that part?
P.S: I am still in beginning stage of learning and not proficient in object-oriented style. If possible, please explain in procedural style.
Edit: I don't understand why my question is closed. I would really like to know from someone that which part of my question is not understandable. English is not my first language and if some parts are not clear enough, at least I deserve specific feedback, not something general like "your question is not clear".
Something like this should work:
$search = array();
$search[] = '%name%';
$replace = array();
$replace[] = $name;
// make sure $_POST['input'] is zero-indexed, otherwise apply `array_values`
foreach ($_POST['input'] as $key => $input) {
$search[] = '%input' . $key . '%';
$replace[] = $input;
}
// next
$template = str_replace($search, $replace, $html);
You can also try this.
$template = '%input2% %input1% %input0% %name%';
$inputarray = [ 'another', "is", "This" ];
foreach ($inputarray as $key => $value) {
$replacement [ '%input'.$key.'%' ] = $value ;
}
$replacement[ "%name%" ] = 'example';
$template = strtr( $template, $replacement );
So I have the following function:
function findMatches($pathToDirectory, $keyword){
$results = array();
$htmlString = "";
$fileList = glob($pathToDirectory);
natsort($fileList);
foreach ($fileList as $search) {
$contents = file_get_contents($search);
$episodeTitle = fgets(fopen($search, 'r'));
$episodeTitle = "<p class='episode_title'>$episodeTitle</p>";
$sentences = preg_split('/(?<=[.])\s+(?=[a-z])/i', $contents);
foreach ($sentences as $sentence) {
if (strpos($sentence, $keyword)) {
if (!in_array($episodeTitle, $results)) {
array_push($results, $episodeTitle);
}
array_push($results, $sentence);
}
}
}
foreach ($results as $result){
$highlightedKeyword = '<span class="keyword_highlight">' . $keyword . '</span>';
$newResult = str_replace($keyword, $highlightedKeyword, $result);
$htmlString .= '<p class="search_result">' . $newResult . '</p>';
}
$totalResults = 'Total Results: <span class=\'number_result\'>' . count($results) . '</span>';
return $htmlString = $totalResults . $htmlString;
}
It opens every text file in a directory ($filelist), takes its contents, splits them up into sentences ($sentences), and then saves the sentences that contain a user defined keyword into an array ($results). Then, it iterates through $results to wrap the keyword in HTML (so that the word appears highlighted within the sentence to the user), and and finally it wraps each sentence in HTML and sends them for presentation to the user.
However, currently the function is case sensitive. What's a good way to make it case insensitive? I tried using stripos() instead of strpos() in the foreach ($sentences as $sentence) loop, and that made the search itself case insensitive (like I want), but the problem is I couldn't figure out how to highlight both upper and lowercase versions of the word correctly if I wrote the function this way.
Also please let me know if you need clarification on any of this, I'm not sure I explained it too well
You need to use stripos() and also str_ireplace() when you're doing your highlighting.
array_push($typedict[$current], "value");
Does not seem to do anything here, i output the associative array of arrays($typedict) but all of them are empty(array()). I print the current associative index out with echo to confirm that it is the correct one(it always is).
Since the print chelc at the end states "[name] => Array()" i have no clue what could be the problem as this indicates that they are indeed arrays and therefore could have stuff pushed in. Also the var $current as stated always have the correct content. at:
echo "current: ". $current;
full code:
<?php
$typedict = array();
$xsdstring = file_get_contents("infile.xsd");
$xsdstring = str_replace("xs:choice", "xs:sequence", $xsdstring);
$doc = new DOMDocument();
$doc->loadXML(mb_convert_encoding($xsdstring, 'utf-8', mb_detect_encoding($xsdstring)));
$xpath = new DOMXPath($doc);
$xpath->registerNamespace('xs', 'http://www.w3.org/2001/XMLSchema');
$xpath->registerNamespace('vc', 'http://www.w3.org/2007/XMLSchema-versioning');
function outputFormat($indent, $elementDef)
{
echo "<div>" . $indent . $elementDef->getAttribute('name')
. " type:" . $elementDef->getAttribute('type')
. " min:" . $elementDef->getAttribute('minOccurs')
. " max:" . $elementDef->getAttribute('maxOccurs')
. "</div>\n";
}
function echoElements($indent = "", $elementDef, $evaluate, &$typedict)
{
global $doc, $xpath, $current;
if($indent == "")
{
$attribute_name = $elementDef->getAttribute('name');
$typedict[$attribute_name] = array();
$current = $attribute_name;
}else{
echo "current: ". $current;
$type = $elementDef->getAttribute('name');
array_push($typedict[$current], "value");
#$typedict[$current][0] = "value";
print_r($typedict[$current]);
}
outputFormat($indent, $elementDef);
$elementDefs = $xpath->evaluate($evaluate, $elementDef);
foreach($elementDefs as $elementDef)
{
echoElements($indent . " ", $elementDef, $evaluate);
}
}
$elementDefs = $xpath->evaluate("/xs:schema/xs:element");
foreach($elementDefs as $elementDef)
{
echoElements("", $elementDef, "xs:complexType/xs:sequence/xs:element", $typedict);
}
$elementDefs = $xpath->evaluate("/xs:schema/xs:complexType");
foreach($elementDefs as $elementDef)
{
echoElements("", $elementDef, "xs:sequence/xs:element", $typedict);
}
print_r($typedict);
?>
$current does contain the correct value. As seen in the code i check it pretty much everytime it gets set. So im pretty confident about that part.
I do not want to change whatever is in $current as it behaves excactly as i want.
My goal is an array inside each entry of the associative array $typedict.
Example:
$typedict["whatever"][0] = "value";
$typedict["whatever"][1] = "value";
...
$current is the index of $typedict not any of it's contents. So in this case $current contains the string "whatever" and not "value". And this is how it should be.
Edit:
I think i figured out the problem. But i have no clue how this could happen and therefore can't fix it:
$typedict["whatever"] seems to be only visible inside the IF block since the last value is okay if chekcked inside the block.
I somehow need to declare the whole structure of $typedict as global. Not just the base array(the associative one) but alos all the arrays inside it. But i only get to know the keys later.
Edit2:
Definetly a visibilty problem:
changing:
global $doc, $xpath, $current;
to:
global $doc, $xpath, $current, $typedict;
solved it
Now, I use strstr to get data from external JSON file. I'm not sure if it's the fastest way to do that what I want and I can't test because json_decode don't work in my code.
$before = '"THIS":"';
$after = '","date"';
$data = strstr(substr($url, strpos($url, $before) + strlen($before)), $after, true)
and with json_decode:
$address = file_get_contents('http://json.link/?something=Hello');
$data = json_decode($address);
echo $data->data->THIS;
Now, when I replace my first code with second I get:
Notice: Trying to get property of non-object
All my code:
$text = "a lot of text";
$text_split = array(0 => '');
$number = 0;
$words = explode(' ', $text);
foreach($words as $word)
{
if(strlen($text_split[$number]) + strlen($word) + 1 > 500)
{
++$number;
$text_split[$number] = '';
}
$text_split[$number] .= $word.' ';
}
foreach($text_split as $texts)
{
$text_encode = rawurlencode($texts);
$address = file_get_contents('http://json.link/?something='.$text_encode);
$data = json_decode($address);
echo $data->data->THIS;
}
What should in do in that case? Keep using strstr or replace all code to work with json_decode (maybe because execution time is faster?)? If the second option, how I can make json_decode work here? Thanks!
... and sorry for bad english.
LE:
If I replace $address = file_get_contents('http://json.link/?something='.$text_encode); with $address = file_get_contents('http://json.link/?something=Hello'); I get VALID result for "Hello" text but 10 times. I guess because it's in a foreach.
json_decode is the suggested method to work with JSON data. Here I think you are trying to access an invalid property in JSON object.
$data = json_decode($address);
echo $data->data->THIS;
I guess you need $data->date instead of $data-data?
you have to access the specific key value like this
$json = '{"success":true,"msg":"success","data":{"THIS":"thing I need","date":"24.03.2014","https":false}}';
$d=json_decode($json,true);
echo $d['data']['THIS'];
when we add a param to the URL
$redirectURL = $printPageURL . "?mode=1";
it works if $printPageURL is "http://www.somesite.com/print.php", but if $printPageURL is changed in the global file to "http://www.somesite.com/print.php?newUser=1", then the URL becomes badly formed. If the project has 300 files and there are 30 files that append param this way, we need to change all 30 files.
the same if we append using "&mode=1" and $printPageURL changes from "http://www.somesite.com/print.php?new=1" to "http://www.somesite.com/print.php", then the URL is also badly formed.
is there a library in PHP that will automatically handle the "?" and "&", and even checks that existing param exists already and removed that one because it will be replaced by the later one and it is not good if the URL keeps on growing longer?
Update: of the several helpful answers, there seems to be no pre-existing function addParam($url, $newParam) so that we don't need to write it?
Use a combination of parse_url() to explode the URL, parse_str() to explode the query string and http_build_query() to rebuild the querystring. After that you can rebuild the whole url from its original fragments you get from parse_url() and the new query string you built with http_build_query(). As the querystring gets exploded into an associative array (key-value-pairs) modifying the query is as easy as modifying an array in PHP.
EDIT
$query = parse_url('http://www.somesite.com/print.php?mode=1&newUser=1', PHP_URL_QUERY);
// $query = "mode=1&newUser=1"
$params = array();
parse_str($query, $params);
/*
* $params = array(
* 'mode' => '1'
* 'newUser' => '1'
* )
*/
unset($params['newUser']);
$params['mode'] = 2;
$params['done'] = 1;
$query = http_build_query($params);
// $query = "mode=2&done=1"
Use this:
http://hu.php.net/manual/en/function.http-build-query.php
http://www.addedbytes.com/php/querystring-functions/
is a good place to start
EDIT: There's also http://www.php.net/manual/en/class.httpquerystring.php
for example:
$http = new HttpQueryString();
$http->set(array('page' => 1, 'sort' => 'asc'));
$url = "yourfile.php" . $http->toString();
None of these solutions work when the url is of the form:
xyz.co.uk?param1=2&replace_this_param=2
param1 gets dropped all the time
.. which means it never works EVER!
If you look at the code given above:
function addParam($url, $s) {
return adjustParam($url, $s);
}
function delParam($url, $s) {
return adjustParam($url, $s);
}
These functions are IDENTICAL - so how can one add and one delete?!
using WishCow and sgehrig's suggestion, here is a test:
(assuming no anchor for the URL)
<?php
echo "<pre>\n";
function adjustParam($url, $s) {
if (preg_match('/(.*?)\?/', $url, $matches)) $urlWithoutParams = $matches[1];
else $urlWithoutParams = $url;
parse_str(parse_url($url, PHP_URL_QUERY), $params);
if (strpos($s, '=') !== false) {
list($var, $value) = split('=', $s);
$params[$var] = urldecode($value);
return $urlWithoutParams . '?' . http_build_query($params);
} else {
unset($params[$s]);
$newQueryString = http_build_query($params);
if ($newQueryString) return $urlWithoutParams . '?' . $newQueryString;
else return $urlWithoutParams;
}
}
function addParam($url, $s) {
return adjustParam($url, $s);
}
function delParam($url, $s) {
return adjustParam($url, $s);
}
echo "trying add:\n";
echo addParam("http://www.somesite.com/print.php", "mode=3"), "\n";
echo addParam("http://www.somesite.com/print.php?", "mode=3"), "\n";
echo addParam("http://www.somesite.com/print.php?newUser=1", "mode=3"), "\n";
echo addParam("http://www.somesite.com/print.php?newUser=1&fee=0", "mode=3"), "\n";
echo addParam("http://www.somesite.com/print.php?newUser=1&fee=0&", "mode=3"), "\n";
echo addParam("http://www.somesite.com/print.php?mode=1", "mode=3"), "\n";
echo "\n", "now trying delete:\n";
echo delParam("http://www.somesite.com/print.php?mode=1", "mode"), "\n";
echo delParam("http://www.somesite.com/print.php?mode=1&newUser=1", "mode"), "\n";
echo delParam("http://www.somesite.com/print.php?mode=1&newUser=1", "newUser"), "\n";
?>
and the output is:
trying add:
http://www.somesite.com/print.php?mode=3
http://www.somesite.com/print.php?mode=3
http://www.somesite.com/print.php?newUser=1&mode=3
http://www.somesite.com/print.php?newUser=1&fee=0&mode=3
http://www.somesite.com/print.php?newUser=1&fee=0&mode=3
http://www.somesite.com/print.php?mode=3
now trying delete:
http://www.somesite.com/print.php
http://www.somesite.com/print.php?newUser=1
http://www.somesite.com/print.php?mode=1
You can try this:
function removeParamFromUrl($query, $paramToRemove)
{
$params = parse_url($query);
if(isset($params['query']))
{
$queryParams = array();
parse_str($params['query'], $queryParams);
if(isset($queryParams[$paramToRemove])) unset($queryParams[$paramToRemove]);
$params['query'] = http_build_query($queryParams);
}
$ret = $params['scheme'].'://'.$params['host'].$params['path'];
if(isset($params['query']) && $params['query'] != '' ) $ret .= '?'.$params['query'];
return $ret;
}