<p>In PHP, how can I replicate the expand/contract feature for Tinyurls as on search.twitter.com?</p>

[{'answer_id': 62367, 'author': 'Paul Dixon', 'author_id': 6521, 'author_profile': 'https://Stackoverflow.com/users/6521', 'pm_score': 4, 'selected': True, 'text': '<p>If you want to find out where a tinyurl is going, use fsockopen to get a connection to tinyurl.com on port 80, and send it an HTTP request like this</p>\n\n<pre><code>GET /dmsfm HTTP/1.0\nHost: tinyurl.com\n</code></pre>\n\n<p>The response you get back will look like</p>\n\n<pre><code>HTTP/1.0 301 Moved Permanently\nConnection: close\nX-Powered-By: PHP/5.2.6\nLocation: http://en.wikipedia.org/wiki/TinyURL\nContent-type: text/html\nContent-Length: 0\nDate: Mon, 15 Sep 2008 12:29:04 GMT\nServer: TinyURL/1.6\n</code></pre>\n\n<p>example code...</p>\n\n<pre><code>&lt;?php\n$tinyurl="dmsfm";\n\n$fp = fsockopen("tinyurl.com", 80, $errno, $errstr, 30);\nif (!$fp) {\n    echo "$errstr ($errno)&lt;br /&gt;\\n";\n} else {\n    $out = "GET /$tinyurl HTTP/1.0\\r\\n";\n    $out .= "Host: tinyurl.com\\r\\n";\n    $out .= "Connection: Close\\r\\n\\r\\n";\n\n    $response="";\n\n    fwrite($fp, $out);\n    while (!feof($fp)) {\n        $response.=fgets($fp, 128);\n    }\n    fclose($fp);\n\n    //now parse the Location: header out of the response\n\n}\n?&gt;\n</code></pre>\n'}, {'answer_id': 62597, 'author': 'Udo', 'author_id': 6907, 'author_profile': 'https://Stackoverflow.com/users/6907', 'pm_score': 2, 'selected': False, 'text': '<p>And here is how to <em>contract</em> an arbitrary URL using the TinyURL API. The general call pattern goes like this, it\'s a simple HTTP request with parameters:</p>\n\n<p><a href="http://tinyurl.com/api-create.php?url=http://insertyourstuffhere.com" rel="nofollow noreferrer">http://tinyurl.com/api-create.php?url=http://insertyourstuffhere.com</a></p>\n\n<p>This will return the corresponding TinyURL for <a href="http://insertyourstuffhere.com" rel="nofollow noreferrer">http://insertyourstuffhere.com</a>. In PHP, you can wrap this in an fsockopen() call or, for convenience, just use the file() function to retrieve it:</p>\n\n<pre><code>function make_tinyurl($longurl)\n{\n  return(implode(\'\', file(\n    \'http://tinyurl.com/api-create.php?url=\'.urlencode($longurl))));\n}\n\n// make an example call\nprint(make_tinyurl(\'http://www.joelonsoftware.com/items/2008/09/15.html\'));\n</code></pre>\n'}, {'answer_id': 63072, 'author': 'barredo', 'author_id': 7398, 'author_profile': 'https://Stackoverflow.com/users/7398', 'pm_score': 0, 'selected': False, 'text': "<p>Another simple and easy way:</p>\n\n<pre><code>&lt;?php\nfunction getTinyUrl($url) {\nreturn file_get_contents('http://tinyurl.com/api-create.php?url='.$url);\n}\n?&gt;\n</code></pre>\n"}, {'answer_id': 63091, 'author': 'dbr', 'author_id': 745, 'author_profile': 'https://Stackoverflow.com/users/745', 'pm_score': 2, 'selected': False, 'text': '<p>As people have answered programatically how to create and resolve tinyurl.com redirects, I\'d like to (strongly) suggest something: caching.</p>\n\n<p>In the twitter example, if every time you clicked the "expand" button, it did an XmlHTTPRequest to, say, <code>/api/resolve_tinyurl/http://tinyurl.com/abcd</code>, then the server created a HTTP connection to tinyurl.com, and inspected the header - it would destroy both twitter and tinyurl\'s servers..</p>\n\n<p>An infinitely more sensible method would be to do something like this Python\'y pseudo-code..</p>\n\n<pre><code>def resolve_tinyurl(url):\n    key = md5( url.lower_case() )\n    if cache.has_key(key)\n        return cache[md5]\n    else:\n        resolved = query_tinyurl(url)\n        cache[key] = resolved\n        return resolved\n</code></pre>\n\n<p>Where <code>cache</code>\'s items magically get backed up into memory, and/or a file, and query_tinyurl() works as Paul Dixon\'s answer does.</p>\n'}, {'answer_id': 1735913, 'author': 'GZipp', 'author_id': 153350, 'author_profile': 'https://Stackoverflow.com/users/153350', 'pm_score': 0, 'selected': False, 'text': "<p>If you just want the location, then do a HEAD request instead of GET.</p>\n\n<pre><code>$tinyurl  = 'http://tinyurl.com/3fvbx8';\n$context  = stream_context_create(array('http' =&gt; array('method' =&gt; 'HEAD')));\n$response = file_get_contents($tinyurl, null, $context);\n\n$location = '';\nforeach ($http_response_header as $header) {\n    if (strpos($header, 'Location:') === 0) {\n        $location = trim(strrchr($header, ' '));\n        break;\n    }\n}\necho $location;\n// http://www.pingdom.com/reports/vb1395a6sww3/check_overview/?name=twitter.com%2Fhome\n</code></pre>\n"}, {'answer_id': 1975639, 'author': 'Pons', 'author_id': 231676, 'author_profile': 'https://Stackoverflow.com/users/231676', 'pm_score': 1, 'selected': False, 'text': '<p>Here is another way to decode short urls via CURL library:</p>\n\n<pre><code>function doShortURLDecode($url) {\n    $ch = @curl_init($url);\n    @curl_setopt($ch, CURLOPT_HEADER, TRUE);\n    @curl_setopt($ch, CURLOPT_NOBODY, TRUE);\n    @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, FALSE);\n    @curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);\n    $response = @curl_exec($ch);\n    preg_match(\'/Location: (.*)\\n/\', $response, $a);\n    if (!isset($a[1])) return $url;\n    return $a[1];\n}\n</code></pre>\n\n<p>It\'s described <a href="http://www.barattalo.it/2009/12/29/tiny-url-encode-and-decode-with-php/" rel="nofollow noreferrer">here</a>.</p>\n'}, {'answer_id': 2021778, 'author': 'Pons', 'author_id': 231676, 'author_profile': 'https://Stackoverflow.com/users/231676', 'pm_score': 0, 'selected': False, 'text': '<p>In PHP there is also a <a href="http://php.net/manual/en/function.get-headers.php" rel="nofollow noreferrer">get_headers</a> function that can be used to decode tiny urls.</p>\n'}, {'answer_id': 57036749, 'author': 'rubo77', 'author_id': 1069083, 'author_profile': 'https://Stackoverflow.com/users/1069083', 'pm_score': 0, 'selected': False, 'text': '<p>The Solution <a href="https://www.barattalo.it/coding/tiny-url-encode-and-decode-with-php/" rel="nofollow noreferrer">here</a> from @Pons solution, didn\'t work alone on my php7.3 server reslolving stackexchange URLs like <code>https://stackoverflow.com/q/62317</code></p>\n\n<p>This solved it:</p>\n\n<pre><code>public function doShortURLDecode($url) {\n    $ch = @curl_init($url);\n    @curl_setopt($ch, CURLOPT_HEADER, TRUE);\n    @curl_setopt($ch, CURLOPT_NOBODY, TRUE);\n    @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, FALSE);\n    @curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);\n    $response = @curl_exec($ch);\n    $cleanresponse= preg_replace(\'/[^A-Za-z0-9\\- _,.:\\n\\/]/\', \'\', $response);\n    preg_match(\'/Location: (.*)[\\n\\r]/\', $cleanresponse, $a);\n    if (!isset($a[1])) return $url;\n    return parse_url($url, PHP_URL_SCHEME).\'://\'.parse_url($url, PHP_URL_HOST).$a[1];\n}\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/62317', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/-1/']