facebook.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815
  1. <?php
  2. class facebook{
  3. const get = 0;
  4. const post = 1;
  5. public function __construct(){
  6. include "lib/nextpage.php";
  7. $this->nextpage = new nextpage("fb");
  8. }
  9. public function getfilters($page){
  10. return [
  11. "sort" => [
  12. "display" => "Sort by",
  13. "option" => [
  14. "relevance" => "Relevance",
  15. "most_recent" => "Most recent"
  16. ]
  17. ],
  18. "newer" => [
  19. "display" => "Newer than",
  20. "option" => "_DATE"
  21. ],
  22. "older" => [
  23. "display" => "Older than",
  24. "option" => "_DATE"
  25. ],
  26. "live" => [
  27. "display" => "Livestream",
  28. "option" => [
  29. "no" => "No",
  30. "yes" => "Yes"
  31. ]
  32. ]
  33. ];
  34. }
  35. private function get($url, $get = [], $reqtype = self::get){
  36. $curlproc = curl_init();
  37. if($get !== []){
  38. $get = http_build_query($get);
  39. if($reqtype === self::get){
  40. $headers = [
  41. "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:115.0) Gecko/20100101 Firefox/115.0",
  42. "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
  43. "Accept-Language: en-US,en;q=0.5",
  44. "Accept-Encoding: gzip",
  45. "DNT: 1",
  46. "Connection: keep-alive",
  47. "Upgrade-Insecure-Requests: 1",
  48. "Sec-Fetch-Dest: document",
  49. "Sec-Fetch-Mode: navigate",
  50. "Sec-Fetch-Site: none",
  51. "Sec-Fetch-User: ?1"
  52. ];
  53. $url .= "?" . $get;
  54. }else{
  55. curl_setopt($curlproc, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
  56. $headers = [
  57. "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:115.0) Gecko/20100101 Firefox/115.0",
  58. "Accept: */*",
  59. "Accept-Language: en-US,en;q=0.5",
  60. "Accept-Encoding: gzip, deflate, br",
  61. "Content-Type: application/x-www-form-urlencoded",
  62. "X-FB-Friendly-Name: SearchCometResultsPaginatedResultsQuery",
  63. //"X-FB-LSD: AVptQC4a16c",
  64. //"X-ASBD-ID: 129477",
  65. "Content-Length: " . strlen($get),
  66. "Origin: https://www.facebook.com",
  67. "DNT: 1",
  68. "Connection: keep-alive",
  69. "Referer: https://www.facebook.com/watch/",
  70. "Cookie: datr=__GMZCgwVF5BbyvAtfJojQwg; oo=v1%7C3%3A1691641171; wd=955x995",
  71. "Sec-Fetch-Dest: empty",
  72. "Sec-Fetch-Mode: cors",
  73. "Sec-Fetch-Site: same-origin",
  74. "TE: trailers"
  75. ];
  76. curl_setopt($curlproc, CURLOPT_POST, true);
  77. curl_setopt($curlproc, CURLOPT_POSTFIELDS, $get);
  78. }
  79. }
  80. curl_setopt($curlproc, CURLOPT_URL, $url);
  81. curl_setopt($curlproc, CURLOPT_ENCODING, ""); // default encoding
  82. curl_setopt($curlproc, CURLOPT_HTTPHEADER, $headers);
  83. curl_setopt($curlproc, CURLOPT_RETURNTRANSFER, true);
  84. curl_setopt($curlproc, CURLOPT_SSL_VERIFYHOST, 2);
  85. curl_setopt($curlproc, CURLOPT_SSL_VERIFYPEER, true);
  86. curl_setopt($curlproc, CURLOPT_CONNECTTIMEOUT, 30);
  87. curl_setopt($curlproc, CURLOPT_TIMEOUT, 30);
  88. $data = curl_exec($curlproc);
  89. if(curl_errno($curlproc)){
  90. throw new Exception(curl_error($curlproc));
  91. }
  92. curl_close($curlproc);
  93. return $data;
  94. }
  95. public function video($get){
  96. $search = $get["s"];
  97. $npt = $get["npt"];
  98. $this->out = [
  99. "status" => "ok",
  100. "npt" => null,
  101. "video" => [],
  102. "author" => [],
  103. "livestream" => [],
  104. "playlist" => [],
  105. "reel" => []
  106. ];
  107. if($get["npt"]){
  108. $nextpage =
  109. json_decode(
  110. $this->nextpage->get(
  111. $npt,
  112. "videos"
  113. ),
  114. true
  115. );
  116. // parse next page
  117. $this->video_nextpage($nextpage);
  118. return $this->out;
  119. }
  120. // generate filter data
  121. // {
  122. // "rp_creation_time:0":"{\"name\":\"creation_time\",\"args\":\"{\\\"start_year\\\":\\\"2023\\\",\\\"start_month\\\":\\\"2023-08\\\",\\\"end_year\\\":\\\"2023\\\",\\\"end_month\\\":\\\"2023-08\\\",\\\"start_day\\\":\\\"2023-08-10\\\",\\\"end_day\\\":\\\"2023-08-10\\\"}\"}",
  123. // "videos_sort_by:0":"{\"name\":\"videos_sort_by\",\"args\":\"Most Recent\"}",
  124. // "videos_live:0":"{\"name\":\"videos_live\",\"args\":\"\"}"
  125. // }
  126. $filter = [];
  127. $sort = $get["sort"];
  128. $live = $get["live"];
  129. $older = $get["older"];
  130. $newer = $get["newer"];
  131. if(
  132. $older !== false ||
  133. $newer !== false
  134. ){
  135. if($older === false){
  136. $older = time();
  137. }
  138. if($newer === false){
  139. $newer = 0;
  140. }
  141. $filter["rp_creation_time:0"] =
  142. json_encode(
  143. [
  144. "name" => "creation_time",
  145. "args" =>
  146. json_encode(
  147. [
  148. "start_year" => date("Y", $newer),
  149. "start_month" => date("Y-m", $newer),
  150. "end_year" => date("Y", $older),
  151. "end_month" => date("Y-m", $older),
  152. "start_day" => date("Y-m-d", $newer),
  153. "end_day" => date("Y-m-d", $older)
  154. ]
  155. )
  156. ]
  157. );
  158. }
  159. if($sort != "relevance"){
  160. $filter["videos_sort_by:0"] =
  161. json_encode(
  162. [
  163. "name" => "videos_sort_by",
  164. "args" => "Most Recent"
  165. ]
  166. );
  167. }
  168. if($live != "no"){
  169. $filter["videos_live:0"] = json_encode(
  170. [
  171. "name" => "videos_live",
  172. "args" => ""
  173. ]
  174. );
  175. }
  176. $req = [
  177. "q" => $search
  178. ];
  179. if(count($filter) !== 0){
  180. $req["filters"] =
  181. base64_encode(
  182. json_encode(
  183. $filter
  184. )
  185. );
  186. }
  187. $html =
  188. $this->get(
  189. "https://www.facebook.com/watch/search/",
  190. $req
  191. );
  192. /*
  193. $handle = fopen("scraper/facebook.html", "r");
  194. $html = fread($handle, filesize("scraper/facebook.html"));
  195. fclose($handle);*/
  196. preg_match_all(
  197. '/({"__bbox":.*,"sequence_number":0}})\]\]/',
  198. $html,
  199. $json
  200. );
  201. if(!isset($json[1][1])){
  202. throw new Exception("Could not grep JSON body");
  203. }
  204. $json = json_decode($json[1][1], true);
  205. foreach(
  206. $json
  207. ["__bbox"]
  208. ["result"]
  209. ["data"]
  210. ["serpResponse"]
  211. ["results"]
  212. ["edges"]
  213. as $result
  214. ){
  215. $this->parse_edge($result);
  216. }
  217. // get nextpage data
  218. if(
  219. $json
  220. ["__bbox"]
  221. ["result"]
  222. ["data"]
  223. ["serpResponse"]
  224. ["results"]
  225. ["page_info"]
  226. ["has_next_page"]
  227. == 1
  228. ){
  229. preg_match(
  230. '/handleWithCustomApplyEach\(ScheduledApplyEach,({.*})\);}\);}\);<\/script>/',
  231. $html,
  232. $nextpagedata
  233. );
  234. // [POST] https://www.facebook.com/api/graphql/
  235. // FORM data, not JSON!
  236. $nextpage = [
  237. "av" => "0",
  238. "__user" => null,
  239. "__a" => null,
  240. "__req" => "2",
  241. "__hs" => null,
  242. "dpr" => "1",
  243. "__ccg" => null,
  244. "__rev" => null,
  245. // another client side token
  246. "__s" => $this->randomstring(6) . ":" . $this->randomstring(6) . ":" . $this->randomstring(6),
  247. "__hsi" => null,
  248. // tracking fingerprint (probably generated using webgl)
  249. "__dyn" => "7xeUmwlE7ibwKBWo2vwAxu13w8CewSwMwNw9G2S0im3y4o0B-q1ew65xO2O1Vw8G1Qw5Mx61vw9m1YwBgao6C0Mo5W3S7Udo5q4U2zxe2Gew9O222SUbEaU2eU5O0GpovU19pobodEGdw46wbS1LwTwNwLw8O1pwr86C16w",
  250. "__csr" => $this->randomstring(null),
  251. "__comet_req" => null,
  252. "lsd" => null,
  253. "jazoest" => null,
  254. "__spin_r" => null,
  255. "__spin_b" => null,
  256. "__spin_t" => null,
  257. "fb_api_caller_class" => "RelayModern",
  258. "fb_api_req_friendly_name" => "SearchCometResultsPaginatedResultsQuery",
  259. "variables" => [ // this is json
  260. "UFI2CommentsProvider_commentsKey" => "SearchCometResultsInitialResultsQuery",
  261. "allow_streaming" => false,
  262. "args" => [
  263. "callsite" => "comet:watch_search",
  264. "config" => [
  265. "exact_match" => false,
  266. "high_confidence_config" => null,
  267. "intercept_config" => null,
  268. "sts_disambiguation" => null,
  269. "watch_config" => null
  270. ],
  271. "context" => [
  272. "bsid" => null,
  273. "tsid" => null
  274. ],
  275. "experience" => [
  276. "encoded_server_defined_params" => null,
  277. "fbid" => null,
  278. "type" => "WATCH_TAB_GLOBAL"
  279. ],
  280. "filters" => [],
  281. "text" => $search
  282. ],
  283. "count" => 5,
  284. "cursor" =>
  285. $json
  286. ["__bbox"]
  287. ["result"]
  288. ["data"]
  289. ["serpResponse"]
  290. ["results"]
  291. ["page_info"]
  292. ["end_cursor"],
  293. "displayCommentsContextEnableComment" => false,
  294. "displayCommentsContextIsAdPreview" => false,
  295. "displayCommentsContextIsAggregatedShare" => false,
  296. "displayCommentsContextIsStorySet" => false,
  297. "displayCommentsFeedbackContext" => null,
  298. "feedLocation" => "SEARCH",
  299. "feedbackSource" => 23,
  300. "fetch_filters" => true,
  301. "focusCommentID" => null,
  302. "locale" => null,
  303. "privacySelectorRenderLocation" => "COMET_STREAM",
  304. "renderLocation" => "search_results_page",
  305. "scale" => 1,
  306. "stream_initial_count" => 0,
  307. "useDefaultActor" => false,
  308. "__relay_internal__pv__IsWorkUserrelayprovider" => false,
  309. "__relay_internal__pv__IsMergQAPollsrelayprovider" => false,
  310. "__relay_internal__pv__StoriesArmadilloReplyEnabledrelayprovider" => false,
  311. "__relay_internal__pv__StoriesRingrelayprovider" => false
  312. ],
  313. "server_timestamps" => "true",
  314. "doc_id" => "6761275837251607" // is actually dynamic
  315. ];
  316. // append filters to nextpage
  317. foreach($filter as $key => $value){
  318. $nextpage["variables"]["args"]["filters"][] =
  319. $value;
  320. }
  321. $nextpagedata = json_decode($nextpagedata[1], true);
  322. // get bsid
  323. foreach($nextpagedata["require"] as $key){
  324. foreach($key as $innerkey){
  325. if(is_array($innerkey)){
  326. foreach($innerkey as $inner_innerkey){
  327. if(is_array($inner_innerkey)){
  328. foreach($inner_innerkey as $inner_inner_innerkey){
  329. if(
  330. isset(
  331. $inner_inner_innerkey
  332. ["variables"]
  333. ["args"]
  334. ["context"]
  335. ["bsid"]
  336. )
  337. ){
  338. $nextpage
  339. ["variables"]
  340. ["args"]
  341. ["context"]
  342. ["bsid"] =
  343. $inner_inner_innerkey
  344. ["variables"]
  345. ["args"]
  346. ["context"]
  347. ["bsid"];
  348. }
  349. }
  350. }
  351. }
  352. }
  353. }
  354. }
  355. foreach($nextpagedata["define"] as $key){
  356. if(isset($key[2]["haste_session"])){
  357. $nextpage["__hs"] = $key[2]["haste_session"];
  358. }
  359. if(isset($key[2]["connectionClass"])){
  360. $nextpage["__ccg"] = $key[2]["connectionClass"];
  361. }
  362. if(isset($key[2]["__spin_r"])){
  363. $nextpage["__spin_r"] = (string)$key[2]["__spin_r"];
  364. }
  365. if(isset($key[2]["hsi"])){
  366. $nextpage["__hsi"] = (string)$key[2]["hsi"];
  367. }
  368. if(
  369. isset($key[2]["token"]) &&
  370. !empty($key[2]["token"])
  371. ){
  372. $nextpage["lsd"] = $key[2]["token"];
  373. }
  374. if(isset($key[2]["__spin_r"])){
  375. $nextpage["__spin_r"] = (string)$key[2]["__spin_r"];
  376. $nextpage["__rev"] = $nextpage["__spin_r"];
  377. }
  378. if(isset($key[2]["__spin_b"])){
  379. $nextpage["__spin_b"] = $key[2]["__spin_b"];
  380. }
  381. if(isset($key[2]["__spin_t"])){
  382. $nextpage["__spin_t"] = (string)$key[2]["__spin_t"];
  383. }
  384. }
  385. preg_match(
  386. '/{"u":"\\\\\/ajax\\\\\/qm\\\\\/\?__a=([0-9]+)&__user=([0-9]+)&__comet_req=([0-9]+)&jazoest=([0-9]+)"/',
  387. $html,
  388. $ajaxparams
  389. );
  390. if(count($ajaxparams) !== 5){
  391. throw new Exception("Could not grep the AJAX parameters");
  392. }
  393. $nextpage["__a"] = $ajaxparams[1];
  394. $nextpage["__user"] = $ajaxparams[2];
  395. $nextpage["__comet_req"] = $ajaxparams[3];
  396. $nextpage["jazoest"] = $ajaxparams[4];
  397. /*
  398. $handle = fopen("scraper/facebook-nextpage.json", "r");
  399. $json = fread($handle, filesize("scraper/facebook-nextpage.json"));
  400. fclose($handle);*/
  401. $nextpage["variables"] = json_encode($nextpage["variables"]);
  402. $this->video_nextpage($nextpage);
  403. }
  404. return $this->out;
  405. }
  406. private function video_nextpage($nextpage, $getcursor = false){
  407. $json =
  408. $this->get(
  409. "https://www.facebook.com/api/graphql/",
  410. $nextpage,
  411. self::post
  412. );
  413. $json = json_decode($json, true);
  414. if($json === null){
  415. throw new Exception("Failed to decode next page JSON");
  416. }
  417. foreach(
  418. $json
  419. ["data"]
  420. ["serpResponse"]
  421. ["results"]
  422. ["edges"]
  423. as $result
  424. ){
  425. $this->parse_edge($result);
  426. }
  427. if(
  428. $json
  429. ["data"]
  430. ["serpResponse"]
  431. ["results"]
  432. ["page_info"]
  433. ["has_next_page"] == 1
  434. ){
  435. $nextpage["variables"] = json_decode($nextpage["variables"], true);
  436. $nextpage["variables"]["cursor"] =
  437. $json
  438. ["data"]
  439. ["serpResponse"]
  440. ["results"]
  441. ["page_info"]
  442. ["end_cursor"];
  443. $nextpage["variables"] = json_encode($nextpage["variables"]);
  444. //change this for second call. after, it's static.
  445. // TODO: csr also updates to longer string
  446. $nextpage["__dyn"] = "7xeUmwlEnwn8K2WnFw9-2i5U4e0yoW3q322aew9G2S0zU20xi3y4o0B-q1ew65xOfxO1Vw8G11xmfz81s8hwGwQw9m1YwBgao6C2O0B85W3S7Udo5qfK0EUjwGzE2swwwJK2W2K0zK5o4q0GpovU19pobodEGdw46wbS1LwTwNwLw8O1pwr86C16w";
  447. // TODO: change this on third and 6th call
  448. //$nextpage["__s"] = $this->randomstring(6) . ":" . explode(":", $nextpage["__s"], 2)[1];
  449. $this->out["npt"] = $this->nextpage->store(json_encode($nextpage), "videos");
  450. }
  451. }
  452. private function parse_edge($edge){
  453. $append = "video";
  454. $edge =
  455. $edge
  456. ["relay_rendering_strategy"]
  457. ["view_model"];
  458. if(
  459. strtolower(
  460. $edge
  461. ["video_metadata_model"]
  462. ["video_broadcast_status"]
  463. )
  464. == "live"
  465. ){
  466. // handle livestream
  467. $duration = "_LIVE";
  468. $append = "livestream";
  469. $timetext = null;
  470. $views =
  471. (int)$edge
  472. ["video_metadata_model"]
  473. ["relative_time_string"];
  474. $url_prefix = "https://www.facebook.com/watch/live/?v=";
  475. }elseif(
  476. stripos(
  477. $edge
  478. ["video_metadata_model"]
  479. ["video_broadcast_status"],
  480. "vod"
  481. ) !== false
  482. ){
  483. // handle VOD format
  484. $timetext = null;
  485. $views =
  486. (int)$edge
  487. ["video_metadata_model"]
  488. ["relative_time_string"];
  489. $duration =
  490. $this->hms2int(
  491. $edge
  492. ["video_thumbnail_model"]
  493. ["video_duration_text"]
  494. );
  495. $url_prefix = "https://www.facebook.com/watch/live/?v=";
  496. }else{
  497. // handle normal format
  498. $timetext =
  499. explode(
  500. " · ",
  501. $edge
  502. ["video_metadata_model"]
  503. ["relative_time_string"],
  504. 2
  505. );
  506. if(count($timetext) === 2){
  507. $views = $this->truncatedcount2int($timetext[1]);
  508. }else{
  509. $views = null;
  510. }
  511. $timetext = strtotime($timetext[0]);
  512. $duration =
  513. $this->hms2int(
  514. $edge
  515. ["video_thumbnail_model"]
  516. ["video_duration_text"]
  517. );
  518. $url_prefix = "https://www.facebook.com/watch/?v=";
  519. }
  520. if(
  521. isset(
  522. $edge
  523. ["video_metadata_model"]
  524. ["video_owner_profile"]
  525. ["uri_token"]
  526. )
  527. ){
  528. $profileurl =
  529. "https://www.facebook.com/watch/" .
  530. $edge
  531. ["video_metadata_model"]
  532. ["video_owner_profile"]
  533. ["uri_token"];
  534. }else{
  535. $profileurl =
  536. $edge
  537. ["video_metadata_model"]
  538. ["video_owner_profile"]
  539. ["url"];
  540. }
  541. $this->out[$append][] = [
  542. "title" =>
  543. $this->limitstrlen(
  544. str_replace(
  545. "\n",
  546. " ",
  547. $edge
  548. ["video_metadata_model"]
  549. ["title"]
  550. ),
  551. 100
  552. ),
  553. "description" =>
  554. empty(
  555. $edge
  556. ["video_metadata_model"]
  557. ["save_description"]
  558. ) ?
  559. null :
  560. str_replace(
  561. "\n",
  562. " ",
  563. $this->limitstrlen(
  564. $edge
  565. ["video_metadata_model"]
  566. ["save_description"]
  567. )
  568. ),
  569. "author" => [
  570. "name" =>
  571. $edge
  572. ["video_metadata_model"]
  573. ["video_owner_profile"]
  574. ["name"],
  575. "url" => $profileurl,
  576. "avatar" => null
  577. ],
  578. "date" => $timetext,
  579. "duration" => $duration,
  580. "views" => $views,
  581. "thumb" =>
  582. [
  583. "url" =>
  584. $edge
  585. ["video_thumbnail_model"]
  586. ["thumbnail_image"]
  587. ["uri"],
  588. "ratio" => "16:9"
  589. ],
  590. "url" =>
  591. $url_prefix .
  592. $edge
  593. ["video_click_model"]
  594. ["click_metadata_model"]
  595. ["video_id"]
  596. ];
  597. }
  598. private function randomstring($len){
  599. if($len === null){
  600. $str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789-";
  601. $len = rand(141, 145);
  602. $c = 61;
  603. }else{
  604. $str = "abcdefghijklmnopqrstuvwxyz123456789";
  605. $c = 34;
  606. }
  607. $out = null;
  608. for($i=0; $i<$len; $i++){
  609. $out .= $str[rand(0, $c)];
  610. }
  611. return $out;
  612. }
  613. private function limitstrlen($text, $len = 300){
  614. return explode("\n", wordwrap($text, $len, "\n"))[0];
  615. }
  616. private function hms2int($time){
  617. $parts = explode(":", $time, 3);
  618. $time = 0;
  619. if(count($parts) === 3){
  620. // hours
  621. $time = $time + ((int)$parts[0] * 3600);
  622. array_shift($parts);
  623. }
  624. if(count($parts) === 2){
  625. // minutes
  626. $time = $time + ((int)$parts[0] * 60);
  627. array_shift($parts);
  628. }
  629. // seconds
  630. $time = $time + (int)$parts[0];
  631. return $time;
  632. }
  633. private function truncatedcount2int($number){
  634. // decimal should always be 1 number long
  635. $number = explode(" ", $number, 2);
  636. $number = $number[0];
  637. $unit = strtolower($number[strlen($number) - 1]);
  638. $tmp = explode(".", $number, 2);
  639. $number = (int)$number;
  640. if(count($tmp) === 2){
  641. $decimal = (int)$tmp[1];
  642. }else{
  643. $decimal = 0;
  644. }
  645. switch($unit){
  646. case "k":
  647. $exponant = 1000;
  648. break;
  649. case "m":
  650. $exponant = 1000000;
  651. break;
  652. case "b";
  653. $exponant = 1000000000;
  654. break;
  655. default:
  656. $exponant = 1;
  657. break;
  658. }
  659. return ($number * $exponant) + ($decimal * ($exponant / 10));
  660. }
  661. }