1
|
|
|
<?php |
2
|
|
|
namespace SEOstats; |
3
|
|
|
|
4
|
|
|
use SEOstats\Common\SEOstatsException as E; |
5
|
|
|
use SEOstats\Config as Config; |
6
|
|
|
use SEOstats\Helper as Helper; |
7
|
|
|
use SEOstats\Services as Service; |
8
|
|
|
|
9
|
|
|
/** SEOstats |
10
|
|
|
* ================================================================================ |
11
|
|
|
* PHP library to request a bunch of SEO-relevant metrics, such as looking up the |
12
|
|
|
* visibilty of a URL within organic search results, Pagespeed analysis, the |
13
|
|
|
* Google Toolbar PageRank, Page-Authority, Backlink-Details, Traffic Statistics, |
14
|
|
|
* social media relevance, comparing competing websites and a lot more. |
15
|
|
|
* ================================================================================ |
16
|
|
|
* @package SEOstats |
17
|
|
|
* @author Stephan Schmitz <[email protected]> |
18
|
|
|
* @copyright Copyright (c) 2010 - present Stephan Schmitz |
19
|
|
|
* @license http://eyecatchup.mit-license.org |
20
|
|
|
* @version CVS: $Id: SEOstats.php, v2.5.2 Rev 31 2013/08/14 13:57:17 ssc Exp $ |
21
|
|
|
* @link https://github.com/eyecatchup/SEOstats/ |
22
|
|
|
* ================================================================================ |
23
|
|
|
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining |
24
|
|
|
* a copy of this software and associated documentation files (the "Software'), |
25
|
|
|
* to deal in the Software without restriction, including without limitation the |
26
|
|
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
27
|
|
|
* copies of the Software, and to permit persons to whom the Software is furnished |
28
|
|
|
* to do so, subject to the following conditions: |
29
|
|
|
* |
30
|
|
|
* The above copyright notice and this permission notice shall be included in all |
31
|
|
|
* copies or substantial portions of the Software. |
32
|
|
|
* |
33
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
34
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
35
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
36
|
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY |
37
|
|
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
38
|
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
39
|
|
|
* ================================================================================ |
40
|
|
|
*/ |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* Check required PHP settings. |
44
|
|
|
*/ |
45
|
|
|
if (!function_exists('curl_init')) { |
46
|
|
|
throw new E('SEOstats requires the PHP CURL extension.'); |
47
|
|
|
exit(); |
48
|
|
|
} |
49
|
|
|
|
50
|
|
|
if (1 == ini_get('safe_mode') || 'on' === strtolower(ini_get('safe_mode'))) { |
51
|
|
|
throw new E('Because some SEOstats functions require the CURLOPT_FOLLOWLOCATION flag, ' . |
52
|
|
|
'you must not run PHP in safe mode! (This flag can not be set in safe mode.)'); |
53
|
|
|
exit(); |
54
|
|
|
} |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* Starting point for the SEOstats library. Example Usage: |
58
|
|
|
* |
59
|
|
|
* <code> |
60
|
|
|
* ... |
61
|
|
|
* $url = 'http://www.domain.tld'; |
62
|
|
|
* |
63
|
|
|
* // Get the Google Toolbar PageRank value. |
64
|
|
|
* $result = \SEOstats\Services\Google::getPageRank($url); |
65
|
|
|
* |
66
|
|
|
* // Get the first 100 results for a Google search for 'query string'. |
67
|
|
|
* $result = \SEOstats\Services\Google::getSerps('query string'); |
68
|
|
|
* |
69
|
|
|
* // Get the first 500 results for a Google search for 'query string'. |
70
|
|
|
* $result = \SEOstats\Services\Google::getSerps('query string', 500); |
71
|
|
|
* |
72
|
|
|
* // Check the first 500 results for a Google search for 'query string' for |
73
|
|
|
* // occurrences of the given domain name and return an array of matching |
74
|
|
|
* // URL's and their position within the serps. |
75
|
|
|
* $result = \SEOstats\Services\Google::getSerps('query string', 500, $url); |
76
|
|
|
* ... |
77
|
|
|
* </code> |
78
|
|
|
* |
79
|
|
|
*/ |
80
|
|
|
class SEOstats |
81
|
|
|
{ |
82
|
|
|
const BUILD_NO = Config\Package::VERSION_CODE; |
83
|
|
|
|
84
|
|
|
protected static $_url, |
85
|
|
|
$_host, |
86
|
|
|
$_lastHtml, |
87
|
|
|
$_lastLoadedUrl, |
88
|
|
|
$_curlopt_proxy, |
89
|
|
|
$_curlopt_proxyuserpwd, |
90
|
|
|
$_ua |
91
|
|
|
= false; |
92
|
|
|
|
93
|
157 |
|
public function __construct($url = false) |
94
|
|
|
{ |
95
|
157 |
|
if (false !== $url) { |
96
|
|
|
self::setUrl($url); |
97
|
|
|
} |
98
|
157 |
|
} |
99
|
|
|
|
100
|
1 |
|
public function Alexa() |
101
|
|
|
{ |
102
|
1 |
|
return new Service\Alexa; |
103
|
|
|
} |
104
|
|
|
|
105
|
1 |
|
public function Google() |
106
|
|
|
{ |
107
|
1 |
|
return new Service\Google; |
108
|
|
|
} |
109
|
|
|
|
110
|
1 |
|
public function Mozscape() |
111
|
|
|
{ |
112
|
1 |
|
return new Service\Mozscape; |
113
|
|
|
} |
114
|
|
|
|
115
|
1 |
|
public function OpenSiteExplorer() |
116
|
|
|
{ |
117
|
1 |
|
return new Service\OpenSiteExplorer; |
118
|
|
|
} |
119
|
|
|
|
120
|
1 |
|
public function SEMRush() |
121
|
|
|
{ |
122
|
1 |
|
return new Service\SemRush; |
123
|
|
|
} |
124
|
|
|
|
125
|
1 |
|
public function Sistrix() |
126
|
|
|
{ |
127
|
1 |
|
return new Service\Sistrix; |
128
|
|
|
} |
129
|
|
|
|
130
|
1 |
|
public function Social() |
131
|
|
|
{ |
132
|
1 |
|
return new Service\Social; |
133
|
|
|
} |
134
|
|
|
|
135
|
1 |
|
public static function getLastLoadedHtml() |
136
|
|
|
{ |
137
|
1 |
|
return self::$_lastHtml; |
138
|
|
|
} |
139
|
|
|
|
140
|
23 |
|
public static function getLastLoadedUrl() |
141
|
|
|
{ |
142
|
23 |
|
return self::$_lastLoadedUrl; |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
/** |
146
|
|
|
* Ensure the URL is set, return default otherwise |
147
|
|
|
* @return string |
148
|
|
|
*/ |
149
|
96 |
|
public static function getUrl($url = false) |
150
|
|
|
{ |
151
|
96 |
|
$url = false !== $url ? $url : self::$_url; |
152
|
96 |
|
return $url; |
153
|
|
|
} |
154
|
|
|
|
155
|
144 |
|
public function setUrl($url) |
156
|
|
|
{ |
157
|
144 |
|
if (false !== Helper\Url::isRfc($url)) { |
158
|
143 |
|
self::$_url = $url; |
159
|
143 |
|
self::$_host = Helper\Url::parseHost($url); |
160
|
143 |
|
} |
161
|
|
|
else { |
162
|
1 |
|
throw new E('Invalid URL!'); |
163
|
|
|
exit(); |
|
|
|
|
164
|
|
|
} |
165
|
143 |
|
return true; |
166
|
|
|
} |
167
|
|
|
|
168
|
2 |
|
public static function getHost($url = false) |
169
|
|
|
{ |
170
|
2 |
|
return Helper\Url::parseHost(self::getUrl($url)); |
171
|
|
|
} |
172
|
|
|
|
173
|
1 |
|
public static function getDomain($url = false) |
|
|
|
|
174
|
|
|
{ |
175
|
1 |
|
return 'http://' . self::getHost($url = false); |
176
|
|
|
} |
177
|
|
|
|
178
|
|
|
/** |
179
|
|
|
* @return DOMDocument |
180
|
|
|
*/ |
181
|
25 |
|
protected static function _getDOMDocument($html) { |
182
|
25 |
|
$doc = new \DOMDocument; |
183
|
25 |
|
@$doc->loadHtml($html); |
|
|
|
|
184
|
25 |
|
return $doc; |
185
|
|
|
} |
186
|
|
|
|
187
|
|
|
/** |
188
|
|
|
* @return DOMXPath |
189
|
|
|
*/ |
190
|
25 |
|
protected static function _getDOMXPath($doc) { |
191
|
25 |
|
$xpath = new \DOMXPath($doc); |
192
|
25 |
|
return $xpath; |
193
|
|
|
} |
194
|
|
|
|
195
|
|
|
/** |
196
|
|
|
* @return HTML string |
197
|
|
|
*/ |
198
|
2 |
|
protected static function _getPage($url) { |
199
|
2 |
|
$url = self::getUrl($url); |
200
|
2 |
|
if (self::getLastLoadedUrl() == $url) { |
201
|
|
|
return self::getLastLoadedHtml(); |
202
|
|
|
} |
203
|
|
|
|
204
|
2 |
|
$html = Helper\HttpRequest::sendRequest($url); |
205
|
2 |
|
if ($html) { |
206
|
2 |
|
self::$_lastLoadedUrl = $url; |
207
|
2 |
|
self::_setHtml($html); |
208
|
2 |
|
return $html; |
209
|
|
|
} |
210
|
|
|
else { |
211
|
|
|
self::noDataDefaultValue(); |
|
|
|
|
212
|
|
|
} |
213
|
|
|
} |
214
|
|
|
|
215
|
3 |
|
protected static function _setHtml($str) |
216
|
|
|
{ |
217
|
3 |
|
self::$_lastHtml = $str; |
218
|
3 |
|
} |
219
|
|
|
|
220
|
59 |
|
protected static function noDataDefaultValue() |
221
|
|
|
{ |
222
|
59 |
|
return Config\DefaultSettings::DEFAULT_RETURN_NO_DATA; |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
/** |
226
|
|
|
* @return Proxy address |
227
|
|
|
*/ |
228
|
12 |
|
public static function getCurloptProxy() |
229
|
|
|
{ |
230
|
12 |
|
return self::$_curlopt_proxy; |
231
|
|
|
} |
232
|
|
|
|
233
|
|
|
/** |
234
|
|
|
* @param Proxy address $curlopt_proxy |
235
|
|
|
*/ |
236
|
|
|
public static function setCurloptProxy($curlopt_proxy) |
237
|
|
|
{ |
238
|
|
|
self::$_curlopt_proxy = $curlopt_proxy; |
239
|
|
|
} |
240
|
|
|
|
241
|
|
|
/** |
242
|
|
|
* @return Proxy auth |
243
|
|
|
*/ |
244
|
12 |
|
public static function getCurloptProxyuserpwd() |
245
|
|
|
{ |
246
|
12 |
|
return self::$_curlopt_proxyuserpwd; |
247
|
|
|
} |
248
|
|
|
|
249
|
|
|
/** |
250
|
|
|
* @param Proxy auth $curlopt_proxyuserpwd |
251
|
|
|
*/ |
252
|
|
|
public static function setCurloptProxyuserpwd($curlopt_proxyuserpwd) |
253
|
|
|
{ |
254
|
|
|
self::$_curlopt_proxyuserpwd = $curlopt_proxyuserpwd; |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
/** |
258
|
|
|
* @return Useragent string |
259
|
|
|
*/ |
260
|
12 |
|
public static function getUserAgent() |
261
|
|
|
{ |
262
|
12 |
|
return self::$_ua; |
263
|
|
|
} |
264
|
|
|
|
265
|
|
|
/** |
266
|
|
|
* @param Useragent string $ua |
267
|
|
|
*/ |
268
|
|
|
public static function setUserAgent($ua) |
269
|
|
|
{ |
270
|
|
|
self::$_ua = $ua; |
271
|
|
|
} |
272
|
|
|
} |
273
|
|
|
|
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.
Unreachable code is most often the result of
return
,die
orexit
statements that have been added for debug purposes.In the above example, the last
return false
will never be executed, because a return statement has already been met in every possible execution path.