├── .gitignore ├── LICENSE.md ├── README.md ├── composer.json ├── index.php ├── phpunit.xml ├── src ├── Answer.php ├── CodeFinder.php ├── CodeParser.php ├── HaveToWriteYourOwnCodeException.php ├── ParsedCode.php ├── StackOverflowBuddy.php ├── Str.php └── UnnecessarilyGratefulException.php └── tests ├── StackOverflowBuddyTest.php └── data ├── answers.json ├── answers2.json ├── badAnswers.json └── questions.json /.gitignore: -------------------------------------------------------------------------------- 1 | composer.lock 2 | vendor 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Stack Overflow Buddy 2 | 3 | Inspired by the revolutionary work done by @drathier and their [stack-overflow-import](https://github.com/drathier/stack-overflow-import), Stack Overflow Buddy is your own personal PHP based Stack Overflow assistant! 4 | 5 | Why spend your valuable time cutting and pasting from StackOverflow when Stack Overflow Buddy can do it for you? Who wouldn't trade all safety checks and only the basest of functionality checks for a bit of convenience? 6 | ### Installation 7 | ``` 8 | composer require brandonshar/stack-overflow-buddy 9 | ``` 10 | Because Stack Overflow Buddy uses untagged libraries, you may need to add the following lines to your composer root 11 | ``` 12 | "minimum-stability": "dev", 13 | "prefer-stable": true 14 | ``` 15 | ```php 16 | # and in your files you use it 17 | use brandonshar\StackOverflowBuddy; 18 | ``` 19 | --- 20 | ### What's it do? 21 | 22 | Just give it a try! 23 | 24 | ```php 25 | StackOverflowBuddy::mergeSort([2,3,1,4]); 26 | // [1, 2, 3, 4] 27 | ``` 28 | 29 | *Impressed?* 30 | 31 | How about 32 | 33 | ```php 34 | StackOverflowBuddy::substringBetweenTwoStrings('platypus', 'pl', 'us'); 35 | // atyp 36 | ``` 37 | --- 38 | ### Wow, how's it work? 39 | If you're impressed, you should probably stop reading here. 40 | 41 | 1. Split the camelCased function call into words 42 | 2. Grab the top scoring PHP tagged questions with those words in the title from StackOverflow's API 43 | 3. Grab the top scoring answers for those questions 44 | 4. Pull any and all code blocks from those answers 45 | 5. Find the first code block that: 46 | 1. Inteprets without error 47 | 2. Contains one or more functions 48 | 3. One of the functions has the same amount of arguments as were passed by the user 49 | 6. Then we throw caution to the wind, eval, and call the new method! 50 | --- 51 | ### Wow, this will change my workflow forever! 52 | It certainly will. But don't forget to use some of that time you're saving to thank the original author of the code you've now absorbed. 53 | 54 | ```php 55 | var_dump(StackOverflowBuddy::giveThanksFor('substringBetweenTwoStrings')); 56 | /* 57 | ["author"]=> 58 | string(18) "Alejandro Iglesias" 59 | ["authorLink"]=> 60 | string(57) "https://stackoverflow.com/users/425741/alejandro-iglesias" 61 | ["questionLink"]=> 62 | string(35) "https://stackoverflow.com/a/9826656" 63 | */ 64 | ``` 65 | --- 66 | 67 | ### What if StackOverflowBuddy can't find any good code for my method? 68 | In the incredibly unlikely (ok... maybe not *incredibly unlikely*) event that StackOverflowBuddy can't find any code that meets your request, it'll throw you a `HaveToWriteYourOwnCodeException` to keep you busy while hopefully someone else gives a better answer on Stack Overflow. 69 | 70 | --- 71 | 72 | ### Testimonials 73 | If you're still on the fence, don't take my word for it; here's what a satisifed reader of the code had to say: 74 | > "I love how this makes on the fly software updates really easy. If I ever need to tweak an algorithm or fix a bug, I just need to submit a really good answer to stack overflow with the updated code. Goodbye source control!" 75 | 76 | > \- [Pseudofailure](https://www.reddit.com/r/PHP/comments/6qzuzj/just_released_a_package_to_cut_out_the/dl1ejwg/) 77 | --- 78 | 79 | ### Warning-ware 80 | You're free to use this package, but if it makes it to your production environment you accept the responsibility of personally telling each of your users that they would be better off hiding their data under their mattress. 81 | 82 | --- 83 | 84 | ### Notes 85 | Keep in mind that every usage of this makes two requests to the StackOverflow API and they will rate-limit you after a certain number of requests per day. But that shouldn't really be an issue since no one sensible would ever use this for anything. 86 | 87 | --- 88 | 89 | ### Contributing 90 | Have a blast. There is currently only one end to end integration test that requires the index.php file to be reachable from a local server. I just used Laravel Valet. This code does not follow PSR-2 and deliberately uses no typehints or visiblity as I decided to do a similar style experiment to the required Zttp library. Even if you're the strictest PHP writer there is, not following a style guide is at best, like the 5th reason you should never use this code. 91 | 92 | --- 93 | 94 | ### License 95 | The Unlicense. If there's a less restrictive license with even less liability, let's go with that. Anyone who thinks that using this license is to the `detriment of my heirs` clearly didn't look at it very carefully. 96 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name":"brandonshar/stack-overflow-buddy", 3 | "description": "A friendly, error prone coding companion", 4 | "require": { 5 | "php": ">=7", 6 | "nikic/php-parser": "^3.1", 7 | "kitetail/zttp": "dev-master", 8 | "tightenco/collect": "^5.4" 9 | }, 10 | "require-dev": { 11 | "phpunit/phpunit": "~6.0", 12 | "mockery/mockery": "0.9.*" 13 | }, 14 | "autoload": { 15 | "psr-4": { 16 | "brandonshar\\": "src/" 17 | } 18 | }, 19 | "minimum-stability": "dev", 20 | "prefer-stable": true 21 | } 22 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 'desc', 16 | 'sort' => 'votes', 17 | 'tagged' => 'php', 18 | 'site' => 'stackoverflow', 19 | 'intitle' => urlencode('merge sort'), 20 | ]) { 21 | echo file_get_contents('tests/data/questions.json'); 22 | } 23 | 24 | elseif (strpos($_SERVER['REQUEST_URI'], '/questions/9401019;1975520;3296203;11827451;17459468;17501545;17503294;18880844;43169004/answers') === 0 && $_GET == [ 25 | 'order' => 'desc', 26 | 'sort' => 'votes', 27 | 'site' => 'stackoverflow', 28 | 'filter' => '!0WyEumH)CFikxBBVsfnDZQar5' 29 | ]) { 30 | echo file_get_contents('tests/data/answers.json'); 31 | } 32 | 33 | elseif (strpos($_SERVER['REQUEST_URI'], '/empty') === 0) { 34 | echo json_encode(['items' => []]); 35 | } 36 | 37 | elseif (strpos($_SERVER['REQUEST_URI'], '/bad') === 0) { 38 | echo file_get_contents('tests/badAnswers.json'); 39 | } 40 | 41 | elseif (strpos($_SERVER['REQUEST_URI'], '/extracode/search') === 0) { 42 | echo file_get_contents('tests/data/questions.json'); 43 | } 44 | 45 | elseif (strpos($_SERVER['REQUEST_URI'], '/extracode/questions') === 0) { 46 | echo file_get_contents('tests/data/answers2.json'); 47 | } 48 | 49 | elseif (strpos($_SERVER['REQUEST_URI'], '/rate-limiting') === 0) { 50 | echo json_encode([]); 51 | } 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ./tests 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Answer.php: -------------------------------------------------------------------------------- 1 | answer = $answer; 10 | $this->code = $code; 11 | } 12 | 13 | function __get($arg) 14 | { 15 | return $this->answer[$arg] ?? null; 16 | } 17 | 18 | function __toString() 19 | { 20 | return $this->code; 21 | } 22 | 23 | function __invoke($args) 24 | { 25 | $this->eval(); 26 | 27 | $method = $this->method; 28 | return $method(...$args); 29 | } 30 | 31 | static function new(...$args) 32 | { 33 | return new self(...$args); 34 | } 35 | 36 | static function null() 37 | { 38 | return new NullAnswer; 39 | } 40 | 41 | function tap($callback) { 42 | $callback($this); 43 | return $this; 44 | } 45 | 46 | function eval() 47 | { 48 | $this->evaled = $this->evaled ?? (eval($this->code) || true); 49 | } 50 | 51 | function attribution() 52 | { 53 | return [ 54 | 'author' => $this->owner['display_name'], 55 | 'authorLink' => $this->owner['link'], 56 | 'questionLink' => $this->share_link 57 | ]; 58 | } 59 | } 60 | 61 | class NullAnswer 62 | { 63 | function __invoke($_) 64 | { 65 | throw new HaveToWriteYourOwnCodeException('Oh no, now we may have to actually think about this!'); 66 | } 67 | 68 | function attribution() 69 | { 70 | throw new UnnecessarilyGratefulException('No one to thank. Are you sure you\'ve been helped?'); 71 | } 72 | } -------------------------------------------------------------------------------- /src/CodeFinder.php: -------------------------------------------------------------------------------- 1 | api = StackOverflowBuddy::$api; 13 | 14 | ZttpResponse::macro('collect', function () { 15 | if (!array_key_exists('items', $this->json())) { 16 | throw new HaveToWriteYourOwnCodeException('Looks like the stackexchange api is tired of helping you'); 17 | } 18 | return collect($this->json()['items']); 19 | }); 20 | } 21 | 22 | static function new() 23 | { 24 | return new self; 25 | } 26 | 27 | function findCode($method) 28 | { 29 | return $this->getAnswers( 30 | $this->getQuestionIds(strtolower(Str::splitCamelCase($method))) 31 | )->map(function ($item) { 32 | return $this->extractCode($item['body'])->map(function ($code) use ($item) { 33 | return Answer::new($item, $code); 34 | }); 35 | })->flatten(); 36 | } 37 | 38 | function getQuestionIds($search) 39 | { 40 | return Zttp::get($this->api.'search', [ 41 | 'order' => 'desc', 42 | 'sort' => 'votes', 43 | 'tagged' => 'php', 44 | 'site' => 'stackoverflow', 45 | 'intitle' => urlencode($search), 46 | ])->collect()->pluck('question_id')->implode(';'); 47 | } 48 | 49 | function getAnswers($questionIds) 50 | { 51 | return $questionIds ? Zttp::get("{$this->api}questions/{$questionIds}/answers", [ 52 | 'order' => 'desc', 53 | 'sort' => 'votes', 54 | 'site' => 'stackoverflow', 55 | 'filter' => '!0WyEumH)CFikxBBVsfnDZQar5', 56 | ])->collect() : collect(); 57 | } 58 | 59 | function extractCode($potentialCode) 60 | { 61 | return collect( 62 | preg_match_all("/(.*?)<\/code>/", str_replace(["\r", "\n"], '', $potentialCode), $results) 63 | ? collect($results[1])->map(function ($code) { return html_entity_decode($code); }) 64 | : false 65 | )->filter(); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/CodeParser.php: -------------------------------------------------------------------------------- 1 | parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP5); 15 | } 16 | 17 | static function instance() { 18 | return static::$instance ?? (static::$instance = new static()); 19 | } 20 | 21 | function parse($answer) 22 | { 23 | try { 24 | return ParsedCode::new($answer, $this->parser->parse("answer = $answer; 12 | $this->parsedCode = collect($parsedCode); 13 | $this->prettyPrinter = new PrettyPrinter\Standard(); 14 | } 15 | 16 | static function new($answer, $parsedCode) 17 | { 18 | $parsedCode = collect($parsedCode); 19 | $isFunction = function ($node) { 20 | return $node instanceof \PhpParser\Node\Stmt\Function_; 21 | }; 22 | 23 | return $parsedCode->contains($isFunction) 24 | ? new static($answer, $parsedCode->filter($isFunction)) 25 | : static::null(); 26 | } 27 | 28 | static function null() 29 | { 30 | return new NullParsedCode; 31 | } 32 | 33 | function attemptExecution($args) 34 | { 35 | return $this->checkArgs($args)->attempt($this->method, $args); 36 | } 37 | 38 | function checkArgs($args) 39 | { 40 | $method = $this->parsedCode->first(function ($code) use ($args) { 41 | return count($args) === count($code->params); 42 | }); 43 | 44 | return ($this->method = $method ? $method->name : false) 45 | ? $this : static::null(); 46 | } 47 | 48 | function attempt($method, $args) 49 | { 50 | return $this->answer->tap(function ($a) use ($args, $method) { 51 | $a->args = $args; 52 | $a->method = $method; 53 | $a->code = $this->prettyPrinter->prettyPrint($this->parsedCode->all()); 54 | }); 55 | } 56 | } 57 | 58 | class NullParsedCode 59 | { 60 | function attemptExecution($_) {} 61 | function attempt($_, $__) {} 62 | } 63 | -------------------------------------------------------------------------------- /src/StackOverflowBuddy.php: -------------------------------------------------------------------------------- 1 | findCode($method) 19 | ->firstMap(function ($answer) use ($args) { 20 | return CodeParser::instance() 21 | ->parse($answer) 22 | ->attemptExecution($args); 23 | }, Answer::null()); 24 | })($args); 25 | } 26 | 27 | static function cache($method, $cacheCallback) 28 | { 29 | return static::$answers[$method] ?? (static::$answers[$method] = $cacheCallback()); 30 | } 31 | 32 | static function giveThanksFor($method) { 33 | return static::get($method)->attribution(); 34 | } 35 | 36 | static function get($method) { 37 | return static::$answers[$method] ?? Answer::null(); 38 | } 39 | 40 | static function setup() 41 | { 42 | // this name kind of sucks. Suggestions would be great! 43 | Collection::macro('firstMap', function ($callback, $default = null) { 44 | foreach ($this as $that) { 45 | $result = $callback($that); 46 | if ($result) { 47 | return $result; 48 | } 49 | } 50 | return $default; 51 | }); 52 | 53 | Collection::macro('dd', function () { 54 | var_dump($this->items); 55 | return $this; 56 | }); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Str.php: -------------------------------------------------------------------------------- 1 | assertEquals([1, 2, 3, 4, 5], StackOverflowBuddy::mergeSort([3, 5, 1, 2, 4])); 21 | } 22 | 23 | function test_it_caches_and_returns_good_code() 24 | { 25 | $this->assertEquals([1, 2, 3, 4, 5], StackOverflowBuddy::mergeSort([3, 5, 1, 2, 4])); 26 | $this->assertEquals([1, 2, 3, 4, 5], StackOverflowBuddy::mergeSort([3, 5, 1, 2, 4])); 27 | } 28 | 29 | function test_it_throws_away_non_function_code() 30 | { 31 | StackOverflowBuddy::$api = 'stackoverflow.dev/extracode/'; 32 | $this->assertEquals(['atyp'], StackOverflowBuddy::getStringBetweenTwoStrings('pl', 'us', 'platypus')); 33 | } 34 | 35 | function test_it_provides_attribution() 36 | { 37 | StackOverflowBuddy::mergeSort([3, 5, 1, 2, 4]); 38 | $this->assertEquals([ 39 | 'author' => 'Kartik', 40 | 'authorLink' => 'https://stackoverflow.com/users/325499/kartik', 41 | 'questionLink' => 'https://stackoverflow.com/a/9401135', 42 | ], StackOverflowBuddy::giveThanksFor('mergeSort')); 43 | 44 | } 45 | 46 | function test_it_doesnt_let_you_thank_no_one() 47 | { 48 | $this->expectException(UnnecessarilyGratefulException::class); 49 | StackOverflowBuddy::giveThanksFor('something'); 50 | } 51 | 52 | function test_it_throws_exception_with_no_results() 53 | { 54 | StackOverflowBuddy::$api = 'stackoverflow.dev/empty/'; 55 | $this->expectException(HaveToWriteYourOwnCodeException::class); 56 | StackOverflowBuddy::anything('x'); 57 | } 58 | 59 | function test_it_throws_exception_with_bad_results() 60 | { 61 | StackOverflowBuddy::$api = 'stackoverflow.dev/bad/'; 62 | $this->expectException(HaveToWriteYourOwnCodeException::class); 63 | StackOverflowBuddy::anything('x'); 64 | } 65 | 66 | function test_it_handles_being_rate_limited_by_stack_overflow() 67 | { 68 | StackOverflowBuddy::$api = 'stackoverflow.dev/rate-limit/'; 69 | $this->expectException(HaveToWriteYourOwnCodeException::class); 70 | StackOverflowBuddy::anything(); 71 | } 72 | } -------------------------------------------------------------------------------- /tests/data/answers.json: -------------------------------------------------------------------------------- 1 | {"items":[{"owner":{"reputation":20223,"user_id":236047,"user_type":"registered","accept_rate":95,"profile_image":"https://www.gravatar.com/avatar/e083220ac33b47364d345eac8f017919?s=128&d=identicon&r=PG","display_name":"Victor Nicollet","link":"https://stackoverflow.com/users/236047/victor-nicollet"},"down_vote_count":0,"up_vote_count":8,"is_accepted":false,"score":8,"answer_id":1975609,"share_link":"https://stackoverflow.com/a/1975609","body":"

To reach a nesting level of 100 on a merge sort, you would need to have an input array of size 2^100(about 1e30), which is impossible. I suspect your recursion is incorrect. For instance, you wrote $start + $end / 2 instead of ($start + $end) / 2.

\n"},{"owner":{"reputation":3304,"user_id":550,"user_type":"registered","profile_image":"https://www.gravatar.com/avatar/a7d85c71a25c4d596f475a4858b5087c?s=128&d=identicon&r=PG","display_name":"Juan","link":"https://stackoverflow.com/users/550/juan"},"down_vote_count":0,"up_vote_count":7,"is_accepted":true,"score":7,"answer_id":9401151,"share_link":"https://stackoverflow.com/a/9401151","body":"

In your merge function, you call count on right instead of $right. PHP assumes this is a string constant (at least in 5.3.9) and when casted into an array that always has one element. So count(right) is always one, and you never exit the first merge.

\n"},{"owner":{"reputation":3476,"user_id":325499,"user_type":"registered","accept_rate":88,"profile_image":"https://www.gravatar.com/avatar/888e80528db858833b400d0a7a83dee4?s=128&d=identicon&r=PG","display_name":"Kartik","link":"https://stackoverflow.com/users/325499/kartik"},"down_vote_count":0,"up_vote_count":4,"is_accepted":false,"score":4,"answer_id":9401135,"share_link":"https://stackoverflow.com/a/9401135","body":"

Try this approach. Instead of shifting it, slice.

\n\n

Also, for in while loop for the merge function, you need to do an and && comparison instead \nof ||

\n\n
function mergeSort($array)\n{\n    if(count($array) == 1 )\n    {\n        return $array;\n    }\n\n    $mid = count($array) / 2;\n    $left = array_slice($array, 0, $mid);\n    $right = array_slice($array, $mid);\n    $left = mergeSort($left);\n    $right = mergeSort($right);\n\n    return merge($left, $right);\n}\n\n\nfunction merge($left, $right)\n{\n    $res = array();\n\n    while (count($left) > 0 && count($right) > 0)\n    {\n        if($left[0] > $right[0])\n        {\n            $res[] = $right[0];\n            $right = array_slice($right , 1);\n        }\n        else\n        {\n            $res[] = $left[0];\n            $left = array_slice($left, 1);\n        }\n    }\n\n    while (count($left) > 0)\n    {\n        $res[] = $left[0];\n        $left = array_slice($left, 1);\n    }\n\n    while (count($right) > 0)\n    {\n        $res[] = $right[0];\n        $right = array_slice($right, 1);\n    }\n\n    return $res;\n}\n
\n"},{"owner":{"reputation":568,"user_id":1158019,"user_type":"registered","profile_image":"https://www.gravatar.com/avatar/d45488fe5137373e0ec63746cc840310?s=128&d=identicon&r=PG","display_name":"Avanche","link":"https://stackoverflow.com/users/1158019/avanche"},"down_vote_count":0,"up_vote_count":3,"is_accepted":false,"score":3,"answer_id":9401208,"share_link":"https://stackoverflow.com/a/9401208","body":"

Have a look at this, the algorithm is already implemented, using array_push and array splice instead of just array_shift.

\n\n
http://www.codecodex.com/wiki/Merge_sort#PHP\n
\n"},{"owner":{"reputation":46,"user_id":231648,"user_type":"unregistered","profile_image":"https://www.gravatar.com/avatar/91a1db323b404f866d5ffe9d1912892f?s=128&d=identicon&r=PG","display_name":"OlegK","link":"https://stackoverflow.com/users/231648/olegk"},"down_vote_count":0,"up_vote_count":1,"is_accepted":false,"score":1,"answer_id":1975580,"share_link":"https://stackoverflow.com/a/1975580","body":"

Set

\n\n
xdebug.max_nesting_level=500 \n
\n\n

in my php.ini

\n"},{"owner":{"reputation":96,"user_id":168255,"user_type":"registered","profile_image":"https://www.gravatar.com/avatar/a95e70ac7b2964b6386b1034473fbe2a?s=128&d=identicon&r=PG","display_name":"Chris Martin","link":"https://stackoverflow.com/users/168255/chris-martin"},"down_vote_count":0,"up_vote_count":1,"is_accepted":false,"score":1,"answer_id":4643794,"share_link":"https://stackoverflow.com/a/4643794","body":"

Here's my working solution, feel free to compare...

\n\n
/**\n * @param array $items array to sort\n * @param int   $l     left index (defaults to 0)\n * @param int   $r     right index (defaults to count($items)-1)\n */\nfunction mergeSort(&$items, $l = 0, $r = null)\n{\n    if (!isset($r)) {\n        $r = count($items) - 1;\n    }\n\n    if ($l < $r) {\n        $m = floor(($r - $l) / 2) + $l;\n        mergeSort($items, $l, $m);\n        mergeSort($items, $m + 1, $r);\n        merge($items, $l, $m, $r);\n    }\n}\n\n/**\n * @param array $items array to merge\n * @param int   $l     left index\n * @param int   $m     middle index\n * @param int   $r     right index\n */\nfunction merge(&$items, $l, $m, $r)\n{\n    $itemsA = array_slice($items, $l, $m + 1 - $l);\n    $itemsB = array_slice($items, $m + 1, ($r + 1) - ($m + 1));\n\n    $a = 0;\n    $aCount = count($itemsA);\n    $b = 0;\n    $bCount = count($itemsB);\n\n    for ($i = $l; $i <= $r; $i++) {\n        if ($a < $aCount && ($b == $bCount || $itemsA[$a] <= $itemsB[$b])) {\n            $items[$i] = $itemsA[$a++];\n        } else {\n            $items[$i] = $itemsB[$b++];\n        }\n    }\n}\n\n$items = array(5,3,6,1,2,3,9,10,7,2,4,8);\nmergeSort($items);\necho implode(',', $items) . \"\\n\";\n
\n\n

Outputs:

\n\n
1,2,2,3,3,4,5,6,7,8,9,10\n
\n"},{"owner":{"reputation":18090,"user_id":64193,"user_type":"registered","accept_rate":94,"profile_image":"https://www.gravatar.com/avatar/6d5d5488960dcb0cab2d02a031e51ba9?s=128&d=identicon&r=PG","display_name":"Scott Saunders","link":"https://stackoverflow.com/users/64193/scott-saunders"},"down_vote_count":0,"up_vote_count":0,"is_accepted":false,"score":0,"answer_id":1975573,"share_link":"https://stackoverflow.com/a/1975573","body":"

There is a maximum function nesting level of '100', and you have reached it. Your recursive function goes too deep.

\n"},{"owner":{"reputation":3758,"user_id":56225,"user_type":"registered","accept_rate":86,"profile_image":"https://i.stack.imgur.com/WpC9A.jpg?s=128&g=1","display_name":"bkildow","link":"https://stackoverflow.com/users/56225/bkildow"},"down_vote_count":0,"up_vote_count":0,"is_accepted":false,"score":0,"answer_id":1975587,"share_link":"https://stackoverflow.com/a/1975587","body":"

From http://www.xdebug.org/docs/all_settings:

\n\n
\n

xdebug.max_nesting_level\n Type: integer, Default value: 100\n Controls the protection mechanism for infinite recursion protection. The value of this setting is the maximum level of nested functions that are allowed before the script will be aborted.

\n
\n\n

You are going too deep in your recursive function triggering this xdebug error. Try raising this limit and see if that helps.

\n\n

Also, here is an interesting article about recursion and PHP: http://www.alternateinterior.com/2006/09/tail-recursion-in-php.html

\n"},{"owner":{"reputation":91152,"user_id":13508,"user_type":"registered","accept_rate":88,"profile_image":"https://www.gravatar.com/avatar/c9e1d852b4d287027fe76f794e506878?s=128&d=identicon&r=PG","display_name":"Álvaro González","link":"https://stackoverflow.com/users/13508/%c3%81lvaro-gonz%c3%a1lez"},"down_vote_count":0,"up_vote_count":0,"is_accepted":false,"score":0,"answer_id":1975599,"share_link":"https://stackoverflow.com/a/1975599","body":"

PHP is not a good language for recursive algorithms. From the manual:

\n\n
\n

It is possible to call recursive\n functions in PHP. However avoid\n recursive function/method calls with\n over 100-200 recursion levels as it\n can smash the stack and cause a\n termination of the current script.

\n
\n\n

If you need to do it in PHP, you'll probably have to find an iterative version of the algorithm. You've hit a hard-coded limit in the language.

\n"},{"owner":{"reputation":1,"user_id":240972,"user_type":"unregistered","profile_image":"https://www.gravatar.com/avatar/795604ba66d65ddf64ee9c01185b4b3e?s=128&d=identicon&r=PG","display_name":"leo","link":"https://stackoverflow.com/users/240972/leo"},"down_vote_count":0,"up_vote_count":0,"is_accepted":false,"score":0,"answer_id":1980751,"share_link":"https://stackoverflow.com/a/1980751","body":"

Cosi dovrebbe funzionare!!!! www.dslpg.it

\n\n
function merge ( &$a, $left,  $center, $right ) { //left = p   right = r  center = q\n    $n1 = $center - $left + 1;\n    $n2 = $right - $center;\n    for ($i = 1; $i <= $n1; $i++) $L[$i] = $a[$left+$i-1];\n    for ($i = 1; $i <= $n2; $i++) $R[$i] = $a[$center+$i];\n    $L[$n1+1] = 99999;\n    $R[$n2+1] = 99999; \n    $i = 1;\n    $j = 1;\n    for ($k = $left; $k <= $right; $k++) {\n        if ($L[$i] <= $R[$j] ) {\n            $a[$k] = $L[$i];\n            echo $a[$k];\n            $i++;\n        }\n        else {\n            $a[$k] = $R[$j];\n            echo $a[$k];\n            $j++;\n        }\n    }\n    return $a;\n}\nfunction merge_sort ( &$a, $left, $right ) { //left = p  right = r\n    if ( $left < $right ) {\n        $center = (int) floor(($left + $right) / 2 );\n\n        merge_sort ($a, $left, $center);\n        merge_sort ($a, $center+1, $right);\n        merge ($a, $left, $center, $right);\n    }\n}\nmerge_sort ( $a, 1, $n );\n
\n"},{"owner":{"reputation":19,"user_id":4577836,"user_type":"registered","profile_image":"https://graph.facebook.com/10152731435562825/picture?type=large","display_name":"Rana Kolta","link":"https://stackoverflow.com/users/4577836/rana-kolta"},"down_vote_count":0,"up_vote_count":0,"is_accepted":false,"score":0,"answer_id":42007590,"share_link":"https://stackoverflow.com/a/42007590","body":"

Your merge sort accepts a list by reference

\n\n
function merge_sort(&$list)\n
\n\n

So you need to assign it the new merged and sorted list. So instead of

\n\n
return merge($left, $right);\n
\n\n

do

\n\n
$list = $this->merge($left, $right);\n
\n\n

That should do it, just remove the exit and fix the count variable

\n"},{"owner":{"reputation":71,"user_id":2304608,"user_type":"registered","profile_image":"https://i.stack.imgur.com/Nn1IO.jpg?s=128&g=1","display_name":"ayan sil","link":"https://stackoverflow.com/users/2304608/ayan-sil"},"down_vote_count":1,"up_vote_count":0,"is_accepted":false,"score":-1,"answer_id":16132508,"share_link":"https://stackoverflow.com/a/16132508","body":"
<?php\n\n                    ###################\n                    #merge sort in php#\n                    ###################\n$ar=array(2,5,4,3);\nprint_r($ar);\necho \"<br/>\";\n$sar=ms($ar);\nprint_r($sar);\necho \"<br/>\";\nfunction ms($tar)\n{   \n$size=count($tar);\nif($size<=1)\n{\n    print_r($tar);\n    echo \"<br/>\";\n    return $tar;\n}   \nelse\n{\n    $middle=(int)($size/2);\n    for($i=0;$i<$middle;$i++)\n    {\n        $left[$i]=$tar[$i];\n    }\n    for($i=$middle,$j=0;$i<$size;$i++,$j++)\n    {\n        $right[$j]=$tar[$i];\n    }\n    $tl=ms($left);\n    $tr=ms($right);\n    $ma=merge($tl,$tr);\n\n    return $ma;\n}\n}\nfunction merge($l,$r)\n{\n\n$sizel=count($l);\n$sizer=count($r);\n$j=0;\nwhile(($sizel>0)||($sizer>0))\n{   \n    if(($sizel>0) && ($sizer>0))\n    {\n        if($l[0]<=$r[0])\n        {\n            $result[$j]=array_shift($l);\n            $j++;\n        }\n        else\n        {\n            $result[$j]=array_shift($r);\n            $j++;\n        }\n\n    }\n    else if($sizel>0)\n    {\n        $result[$j]=array_shift($l);    \n        $j++;   \n    }\n    else\n    {\n        $result[$j]=array_shift($r);\n        $j++;\n    }\n    $sizel=count($l);\n    $sizer=count($r);\n}\n    return $result; \n}\n?>\n
\n"}],"has_more":false,"quota_max":300,"quota_remaining":273} -------------------------------------------------------------------------------- /tests/data/answers2.json: -------------------------------------------------------------------------------- 1 | {"items":[{"owner":{"reputation":23568,"user_id":219118,"user_type":"registered","profile_image":"https://www.gravatar.com/avatar/a5a89ebe2152ed3c5de458a97542b0ed?s=128&d=identicon&r=PG","display_name":"sachleen","link":"https://stackoverflow.com/users/219118/sachleen"},"down_vote_count":0,"up_vote_count":20,"is_accepted":true,"score":20,"answer_id":14313097,"share_link":"https://stackoverflow.com/a/14313097","body":"

You can just explode it:

\n\n
<?php\n$string = 'reply-234-private';\n$display = explode('-', $string);\n\nvar_dump($display);\n// prints array(3) { [0]=> string(5) \"reply\" [1]=> string(3) \"234\" [2]=> string(7) \"private\" }\n\necho $display[1];\n// prints 234\n
\n\n

Or, use preg_match

\n\n
<?php\n$string = 'reply-234-private';\nif (preg_match('/reply-(.*?)-private/', $string, $display) === 1) {\n    echo $display[1];\n}\n
\n"},{"owner":{"reputation":184,"user_id":1976345,"user_type":"registered","accept_rate":43,"profile_image":"https://www.gravatar.com/avatar/01ea0ca6ffe27dd2823c3b586445bcda?s=128&d=identicon&r=PG","display_name":"Chris Jackson","link":"https://stackoverflow.com/users/1976345/chris-jackson"},"down_vote_count":0,"up_vote_count":7,"is_accepted":false,"score":7,"answer_id":14313112,"share_link":"https://stackoverflow.com/a/14313112","body":"

Have a look at explode() function

\n\n

something like this:

\n\n
$myString = 'reply-234-private';\n\n$myStringPartsArray = explode(\"-\", $myString);\n\n$answer = $myStringPartsArray[1];\n
\n"},{"owner":{"reputation":101,"user_id":3967957,"user_type":"registered","profile_image":"https://graph.facebook.com/100007955027846/picture?type=large","display_name":"Kuncara Kurniawan","link":"https://stackoverflow.com/users/3967957/kuncara-kurniawan"},"down_vote_count":0,"up_vote_count":5,"is_accepted":false,"score":5,"answer_id":27483387,"share_link":"https://stackoverflow.com/a/27483387","body":"

This article show you, How to get of everything string between two tags or two strings.

\n\n

http://okeschool.com/articles/312/string/how-to-get-of-everything-string-between-two-tag-or-two-strings

\n\n
<?php\n // Create the Function to get the string\n function GetStringBetween ($string, $start, $finish) {\n    $string = \" \".$string;\n    $position = strpos($string, $start);\n    if ($position == 0) return \"\";\n    $position += strlen($start);\n    $length = strpos($string, $finish, $position) - $position;\n    return substr($string, $position, $length);\n}\n?>\n
\n\n

in case your question, you can try this :

\n\n
$string1='reply-234-private';\necho GetStringBetween ($string1, \"-\", \"-\")\n
\n\n

or we can use any 'identifier string' for grab the string between the identifier string. for example:

\n\n
echo GetStringBetween ($string1, \"reply-\", \"-private\")\n
\n"},{"owner":{"reputation":171,"user_id":520896,"user_type":"registered","profile_image":"https://www.gravatar.com/avatar/799b0844613573b120c2dda72a69a0e8?s=128&d=identicon&r=PG","display_name":"Ravi Verma","link":"https://stackoverflow.com/users/520896/ravi-verma"},"down_vote_count":1,"up_vote_count":5,"is_accepted":false,"score":4,"answer_id":15093614,"share_link":"https://stackoverflow.com/a/15093614","body":"

Use php's inbuilt regex support functions\npreg_match_all

\n\n

this would help, suppose you want the array of strings(keys) between @@ in following example, where '/' doesn't fall in-between, you can built new example with different start an end variable

\n\n
function getInbetweenStrings($start, $end, $str){\n    $matches = array();\n    $regex = \"/$start([a-zA-Z0-9_]*)$end/\";\n    preg_match_all($regex, $str, $matches);\n    return $matches[1];\n}\n\n$str = \"C://@@ad_custom_attr1@@/@@upn@@/@@samaccountname@@\";\n$str_arr = getInbetweenStrings('@@', '@@', $str);\n\nprint_r($str_arr);\n
\n"},{"owner":{"reputation":84,"user_id":1847939,"user_type":"registered","accept_rate":12,"profile_image":"https://www.gravatar.com/avatar/2c2014d16dd1864c7e380fca91267755?s=128&d=identicon&r=PG","display_name":"szikael","link":"https://stackoverflow.com/users/1847939/szikael"},"down_vote_count":0,"up_vote_count":2,"is_accepted":false,"score":2,"answer_id":20826440,"share_link":"https://stackoverflow.com/a/20826440","body":"
$myString = 'reply-234-private';\necho str_replace('-','',filter_var($myString,FILTER_SANITIZE_NUMBER_INT));\n
\n\n

That should do the job.

\n"},{"owner":{"reputation":51,"user_id":2951807,"user_type":"registered","profile_image":"https://www.gravatar.com/avatar/8acdc2b48025c8db7f09af79be7aedf6?s=128&d=identicon&r=PG&f=1","display_name":"user2951807","link":"https://stackoverflow.com/users/2951807/user2951807"},"down_vote_count":0,"up_vote_count":1,"is_accepted":false,"score":1,"answer_id":29971866,"share_link":"https://stackoverflow.com/a/29971866","body":"

If you want to do it in js, try this function -

\n\n
function getStringBetween(str , fromStr , toStr){\n  var fromStrIndex = str.indexOf(fromStr) == -1 ? 0 : str.indexOf(fromStr) + fromStr.length;\n  var toStrIndex = str.slice(fromStrIndex).indexOf(toStr) == -1 ? str.length-1 : str.slice(fromStrIndex).indexOf(toStr) + fromStrIndex;\n  var strBtween = str.substring(fromStrIndex,toStrIndex);\n  return strBtween;\n}\n
\n"},{"owner":{"reputation":136,"user_id":5870505,"user_type":"registered","profile_image":"https://www.gravatar.com/avatar/ea52d19a3204b0e6841ec375dc68058e?s=128&d=identicon&r=PG&f=1","display_name":"Alexis Ochoa","link":"https://stackoverflow.com/users/5870505/alexis-ochoa"},"down_vote_count":0,"up_vote_count":0,"is_accepted":false,"score":0,"answer_id":35834078,"share_link":"https://stackoverflow.com/a/35834078","body":"

The function strpos implements a offset param.

\n\n

Try this

\n\n
function getdatabetween($string, $start, $end, $offset){\n        $sp = strpos($string, $start, $offset)+strlen($start);\n        $ep = strpos($string, $end, $offset)-strlen($start);\n        $data = trim(substr($string, $sp, $ep));\n        return trim($data);\n}\n
\n"}],"has_more":false,"quota_max":300,"quota_remaining":295} -------------------------------------------------------------------------------- /tests/data/badAnswers.json: -------------------------------------------------------------------------------- 1 | {"items":[{"owner":{"reputation":20223,"user_id":236047,"user_type":"registered","accept_rate":95,"profile_image":"https://www.gravatar.com/avatar/e083220ac33b47364d345eac8f017919?s=128&d=identicon&r=PG","display_name":"Victor Nicollet","link":"https://stackoverflow.com/users/236047/victor-nicollet"},"down_vote_count":0,"up_vote_count":8,"is_accepted":false,"score":8,"answer_id":1975609,"share_link":"https://stackoverflow.com/a/1975609","body":"

To reach a nesting level of 100 on a merge sort, you would need to have an input array of size 2^100(about 1e30), which is impossible. I suspect your recursion is incorrect. For instance, you wrote $start + $end / 2 instead of ($start + $end) / 2.

\n"},{"owner":{"reputation":3304,"user_id":550,"user_type":"registered","profile_image":"https://www.gravatar.com/avatar/a7d85c71a25c4d596f475a4858b5087c?s=128&d=identicon&r=PG","display_name":"Juan","link":"https://stackoverflow.com/users/550/juan"},"down_vote_count":0,"up_vote_count":7,"is_accepted":true,"score":7,"answer_id":9401151,"share_link":"https://stackoverflow.com/a/9401151","body":"

In your merge function, you call count on right instead of $right. PHP assumes this is a string constant (at least in 5.3.9) and when casted into an array that always has one element. So count(right) is always one, and you never exit the first merge.

\n"},{"owner":{"reputation":3476,"user_id":325499,"user_type":"registered","accept_rate":88,"profile_image":"https://www.gravatar.com/avatar/888e80528db858833b400d0a7a83dee4?s=128&d=identicon&r=PG","display_name":"Kartik","link":"https://stackoverflow.com/users/325499/kartik"},"down_vote_count":0,"up_vote_count":4,"is_accepted":false,"score":4,"answer_id":9401135,"share_link":"https://stackoverflow.com/a/9401135","body":"

Try this approach. Instead of shifting it, slice.

\n\n

Also, for in while loop for the merge function, you need to do an and && comparison instead \nof ||

\n\n
function mergeSort($array)\n{\n    ifcount($array) == 1 )\n    {\n        return $array;\n    }\n\n    $mid = count($array) / 2;\n    $left = array_slice($array, 0, $mid);\n    $right = array_slice($array, $mid);\n    $left = mergeSort($left);\n    $right = mergeSort($right);\n\n    return merge($left, $right);\n}\n\n\nfunction merge($left, $right)\n{\n    $res = array();\n\n    while (count($left) > 0 && count($right) > 0)\n    {\n        if($left[0] > $right[0])\n        {\n            $res[] = $right[0];\n            $right = array_slice($right , 1);\n        }\n        else\n        {\n            $res[] = $left[0];\n            $left = array_slice($left, 1);\n        }\n    }\n\n    while (count($left) > 0)\n    {\n        $res[] = $left[0];\n        $left = array_slice($left, 1);\n    }\n\n    while (count($right) > 0)\n    {\n        $res[] = $right[0];\n        $right = array_slice($right, 1);\n    }\n\n    return $res;\n}\n
\n"},{"owner":{"reputation":568,"user_id":1158019,"user_type":"registered","profile_image":"https://www.gravatar.com/avatar/d45488fe5137373e0ec63746cc840310?s=128&d=identicon&r=PG","display_name":"Avanche","link":"https://stackoverflow.com/users/1158019/avanche"},"down_vote_count":0,"up_vote_count":3,"is_accepted":false,"score":3,"answer_id":9401208,"share_link":"https://stackoverflow.com/a/9401208","body":"

Have a look at this, the algorithm is already implemented, using array_push and array splice instead of just array_shift.

\n\n
http://www.codecodex.com/wiki/Merge_sort#PHP\n
\n"},{"owner":{"reputation":46,"user_id":231648,"user_type":"unregistered","profile_image":"https://www.gravatar.com/avatar/91a1db323b404f866d5ffe9d1912892f?s=128&d=identicon&r=PG","display_name":"OlegK","link":"https://stackoverflow.com/users/231648/olegk"},"down_vote_count":0,"up_vote_count":1,"is_accepted":false,"score":1,"answer_id":1975580,"share_link":"https://stackoverflow.com/a/1975580","body":"

Set

\n\n
xdebug.max_nesting_level=500 \n
\n\n

in my php.ini

\n"},{"owner":{"reputation":96,"user_id":168255,"user_type":"registered","profile_image":"https://www.gravatar.com/avatar/a95e70ac7b2964b6386b1034473fbe2a?s=128&d=identicon&r=PG","display_name":"Chris Martin","link":"https://stackoverflow.com/users/168255/chris-martin"},"down_vote_count":0,"up_vote_count":1,"is_accepted":false,"score":1,"answer_id":4643794,"share_link":"https://stackoverflow.com/a/4643794","body":"

Here's my working solution, feel free to compare...

\n\n
/**\n * @param array $items array to sort\n * @param int   $l     left index (defaults to 0)\n * @param int   $r     right index (defaults to count($items)-1)\n */\nfunction mergeSort(&$items, $l = 0, $r = null)\n{\n    if (!isset($r)) {\n        $r = count($items) - 1;\n    }\n\n    if ($l < $r) {\n        $m = floor(($r - $l) / 2) + $l;\n        mergeSort($items, $l, $m);\n        mergeSort($items, $m + 1, $r);\n        merge($items, $l, $m, $r);\n    }\n}\n\n/**\n * @param array $items array to merge\n * @param int   $l     left index\n * @param int   $m     middle index\n * @param int   $r     right index\n */\nfunction merge(&$items, $l, $m, $r)\n{\n    $itemsA = array_slice($items, $l, $m + 1 - $l);\n    $itemsB = array_slice($items, $m + 1, ($r + 1) - ($m + 1));\n\n    $a = 0;\n    $aCount = count($itemsA);\n    $b = 0;\n    $bCount = count($itemsB);\n\n    for ($i = $l; $i <= $r; $i++) {\n        if ($a < $aCount && ($b == $bCount || $itemsA[$a] <= $itemsB[$b])) {\n            $items[$i] = $itemsA[$a++];\n        } else {\n            $items[$i] = $itemsB[$b++];\n        }\n    }\n}\n\n$items = array(5,3,6,1,2,3,9,10,7,2,4,8);\nmergeSort($items);\necho implode(',', $items) . \"\\n\";\n
\n\n

Outputs:

\n\n
1,2,2,3,3,4,5,6,7,8,9,10\n
\n"},{"owner":{"reputation":18090,"user_id":64193,"user_type":"registered","accept_rate":94,"profile_image":"https://www.gravatar.com/avatar/6d5d5488960dcb0cab2d02a031e51ba9?s=128&d=identicon&r=PG","display_name":"Scott Saunders","link":"https://stackoverflow.com/users/64193/scott-saunders"},"down_vote_count":0,"up_vote_count":0,"is_accepted":false,"score":0,"answer_id":1975573,"share_link":"https://stackoverflow.com/a/1975573","body":"

There is a maximum function nesting level of '100', and you have reached it. Your recursive function goes too deep.

\n"},{"owner":{"reputation":3758,"user_id":56225,"user_type":"registered","accept_rate":86,"profile_image":"https://i.stack.imgur.com/WpC9A.jpg?s=128&g=1","display_name":"bkildow","link":"https://stackoverflow.com/users/56225/bkildow"},"down_vote_count":0,"up_vote_count":0,"is_accepted":false,"score":0,"answer_id":1975587,"share_link":"https://stackoverflow.com/a/1975587","body":"

From http://www.xdebug.org/docs/all_settings:

\n\n
\n

xdebug.max_nesting_level\n Type: integer, Default value: 100\n Controls the protection mechanism for infinite recursion protection. The value of this setting is the maximum level of nested functions that are allowed before the script will be aborted.

\n
\n\n

You are going too deep in your recursive function triggering this xdebug error. Try raising this limit and see if that helps.

\n\n

Also, here is an interesting article about recursion and PHP: http://www.alternateinterior.com/2006/09/tail-recursion-in-php.html

\n"},{"owner":{"reputation":91152,"user_id":13508,"user_type":"registered","accept_rate":88,"profile_image":"https://www.gravatar.com/avatar/c9e1d852b4d287027fe76f794e506878?s=128&d=identicon&r=PG","display_name":"Álvaro González","link":"https://stackoverflow.com/users/13508/%c3%81lvaro-gonz%c3%a1lez"},"down_vote_count":0,"up_vote_count":0,"is_accepted":false,"score":0,"answer_id":1975599,"share_link":"https://stackoverflow.com/a/1975599","body":"

PHP is not a good language for recursive algorithms. From the manual:

\n\n
\n

It is possible to call recursive\n functions in PHP. However avoid\n recursive function/method calls with\n over 100-200 recursion levels as it\n can smash the stack and cause a\n termination of the current script.

\n
\n\n

If you need to do it in PHP, you'll probably have to find an iterative version of the algorithm. You've hit a hard-coded limit in the language.

\n"},{"owner":{"reputation":1,"user_id":240972,"user_type":"unregistered","profile_image":"https://www.gravatar.com/avatar/795604ba66d65ddf64ee9c01185b4b3e?s=128&d=identicon&r=PG","display_name":"leo","link":"https://stackoverflow.com/users/240972/leo"},"down_vote_count":0,"up_vote_count":0,"is_accepted":false,"score":0,"answer_id":1980751,"share_link":"https://stackoverflow.com/a/1980751","body":"

Cosi dovrebbe funzionare!!!! www.dslpg.it

\n\n
function merge ( &$a, $left,  $center, $right ) { //left = p   right = r  center = q\n    $n1 = $center - $left + 1;\n    $n2 = $right - $center;\n    for ($i = 1; $i <= $n1; $i++) $L[$i] = $a[$left+$i-1];\n    for ($i = 1; $i <= $n2; $i++) $R[$i] = $a[$center+$i];\n    $L[$n1+1] = 99999;\n    $R[$n2+1] = 99999; \n    $i = 1;\n    $j = 1;\n    for ($k = $left; $k <= $right; $k++) {\n        if ($L[$i] <= $R[$j] ) {\n            $a[$k] = $L[$i];\n            echo $a[$k];\n            $i++;\n        }\n        else {\n            $a[$k] = $R[$j];\n            echo $a[$k];\n            $j++;\n        }\n    }\n    return $a;\n}\nfunction merge_sort ( &$a, $left, $right ) { //left = p  right = r\n    if ( $left < $right ) {\n        $center = (int) floor(($left + $right) / 2 );\n\n        merge_sort ($a, $left, $center);\n        merge_sort ($a, $center+1, $right);\n        merge ($a, $left, $center, $right);\n    }\n}\nmerge_sort ( $a, 1, $n );\n
\n"},{"owner":{"reputation":19,"user_id":4577836,"user_type":"registered","profile_image":"https://graph.facebook.com/10152731435562825/picture?type=large","display_name":"Rana Kolta","link":"https://stackoverflow.com/users/4577836/rana-kolta"},"down_vote_count":0,"up_vote_count":0,"is_accepted":false,"score":0,"answer_id":42007590,"share_link":"https://stackoverflow.com/a/42007590","body":"

Your merge sort accepts a list by reference

\n\n
function merge_sort(&$list)\n
\n\n

So you need to assign it the new merged and sorted list. So instead of

\n\n
return merge($left, $right);\n
\n\n

do

\n\n
$list = $this->merge($left, $right);\n
\n\n

That should do it, just remove the exit and fix the count variable

\n"},{"owner":{"reputation":71,"user_id":2304608,"user_type":"registered","profile_image":"https://i.stack.imgur.com/Nn1IO.jpg?s=128&g=1","display_name":"ayan sil","link":"https://stackoverflow.com/users/2304608/ayan-sil"},"down_vote_count":1,"up_vote_count":0,"is_accepted":false,"score":-1,"answer_id":16132508,"share_link":"https://stackoverflow.com/a/16132508","body":"
<?php\n\n                    ###################\n                    #merge sort in php#\n                    ###################\n$ar=array(2,5,4,3);\nprint_r($ar);\necho \"<br/>\";\n$sar=ms($ar);\nprint_r($sar);\necho \"<br/>\";\nfunction ms($tar)\n{   \n$size=count($tar);\nif($size<=1)\n{\n    print_r($tar);\n    echo \"<br/>\";\n    return $tar;\n}   \nelse\n{\n    $middle=(int)($size/2);\n    for($i=0;$i<$middle;$i++)\n    {\n        $left[$i]=$tar[$i];\n    }\n    for($i=$middle,$j=0;$i<$size;$i++,$j++)\n    {\n        $right[$j]=$tar[$i];\n    }\n    $tl=ms($left);\n    $tr=ms($right);\n    $ma=merge($tl,$tr);\n\n    return $ma;\n}\n}\nfunction merge($l,$r)\n{\n\n$sizel=count($l);\n$sizer=count($r);\n$j=0;\nwhile(($sizel>0)||($sizer>0))\n{   \n    if(($sizel>0) && ($sizer>0))\n    {\n        if($l[0]<=$r[0])\n        {\n            $result[$j]=array_shift($l);\n            $j++;\n        }\n        else\n        {\n            $result[$j]=array_shift($r);\n            $j++;\n        }\n\n    }\n    else if($sizel>0)\n    {\n        $result[$j]=array_shift($l);    \n        $j++;   \n    }\n    else\n    {\n        $result[$j]=array_shift($r);\n        $j++;\n    }\n    $sizel=count($l);\n    $sizer=count($r);\n}\n    return $result; \n}\n?>\n
\n"}],"has_more":false,"quota_max":300,"quota_remaining":273} -------------------------------------------------------------------------------- /tests/data/questions.json: -------------------------------------------------------------------------------- 1 | {"items":[{"tags":["php","sorting","mergesort"],"owner":{"reputation":15,"user_id":1216806,"user_type":"registered","profile_image":"https://www.gravatar.com/avatar/4897e27c476f7232c54f89ec2cb0d39f?s=128&d=identicon&r=PG","display_name":"jweb","link":"https://stackoverflow.com/users/1216806/jweb"},"is_answered":true,"view_count":9109,"accepted_answer_id":9401151,"answer_count":5,"score":2,"last_activity_date":1486053527,"creation_date":1329936343,"last_edit_date":1329936560,"question_id":9401019,"link":"https://stackoverflow.com/questions/9401019/writing-merge-sort-in-php","title":"Writing merge sort in PHP"},{"tags":["php","algorithm","sorting"],"owner":{"reputation":28,"user_id":220508,"user_type":"unregistered","profile_image":"https://www.gravatar.com/avatar/c3b68d4f630aae909f50a1405280a4a3?s=128&d=identicon&r=PG","display_name":"lordlinier","link":"https://stackoverflow.com/users/220508/lordlinier"},"is_answered":true,"view_count":1803,"answer_count":7,"score":1,"last_activity_date":1294635427,"creation_date":1262104370,"question_id":1975520,"link":"https://stackoverflow.com/questions/1975520/question-about-merge-sort-under-php","title":"question about merge sort under php"},{"tags":["php","multidimensional-array"],"owner":{"reputation":6,"user_id":397494,"user_type":"registered","profile_image":"https://www.gravatar.com/avatar/5b38b0afa683b2fc1f4b593a1ce6d0db?s=128&d=identicon&r=PG","display_name":"LeRoy Miller","link":"https://stackoverflow.com/users/397494/leroy-miller"},"is_answered":true,"view_count":1022,"answer_count":2,"score":1,"last_activity_date":1279687087,"creation_date":1279684570,"last_edit_date":1279684675,"question_id":3296203,"link":"https://stackoverflow.com/questions/3296203/php-need-to-merge-sort-a-multidimensional-array-based-on-one-key-in-the-dimensi","title":"PHP: Need to merge/sort a multidimensional array based on one key in the dimension"},{"tags":["php"],"owner":{"reputation":15346,"user_id":465546,"user_type":"registered","accept_rate":94,"profile_image":"https://www.gravatar.com/avatar/d67cc0a6798555fd468d2d5a00ae9927?s=128&d=identicon&r=PG","display_name":"qwertymk","link":"https://stackoverflow.com/users/465546/qwertymk"},"is_answered":true,"view_count":1007,"accepted_answer_id":11827593,"answer_count":1,"score":1,"last_activity_date":1344254792,"creation_date":1344252824,"question_id":11827451,"link":"https://stackoverflow.com/questions/11827451/merge-two-arrays-merge-sort-style","title":"merge two arrays, merge-sort style"},{"tags":["php","sorting"],"owner":{"reputation":12967,"user_id":392975,"user_type":"registered","accept_rate":63,"profile_image":"https://www.gravatar.com/avatar/a62bcec9b5b35a3cab7c25a44016e0d4?s=128&d=identicon&r=PG","display_name":"Eli","link":"https://stackoverflow.com/users/392975/eli"},"is_answered":true,"view_count":3541,"accepted_answer_id":17459600,"answer_count":2,"score":1,"last_activity_date":1372895143,"creation_date":1372892583,"last_edit_date":1372893515,"question_id":17459468,"link":"https://stackoverflow.com/questions/17459468/merge-sort-together-two-arrays-in-php","title":"Merge Sort Together Two Arrays in Php?"},{"tags":["php","mergesort"],"owner":{"reputation":3427,"user_id":237107,"user_type":"registered","accept_rate":71,"profile_image":"https://i.stack.imgur.com/poBfS.jpg?s=128&g=1","display_name":"noctilux","link":"https://stackoverflow.com/users/237107/noctilux"},"is_answered":true,"view_count":385,"accepted_answer_id":17510548,"answer_count":3,"score":0,"last_activity_date":1433225398,"creation_date":1373102674,"question_id":17501545,"link":"https://stackoverflow.com/questions/17501545/counting-inversions-using-merge-sort-unexpected-result","title":"Counting Inversions using merge sort - unexpected result"},{"tags":["php","c++","sorting"],"owner":{"reputation":15,"user_id":1973869,"user_type":"registered","accept_rate":100,"profile_image":"https://www.gravatar.com/avatar/643dded419ebe75ef9d21db21dfa6de5?s=128&d=identicon&r=PG","display_name":"FireForce","link":"https://stackoverflow.com/users/1973869/fireforce"},"is_answered":true,"view_count":468,"accepted_answer_id":17503488,"answer_count":1,"score":0,"last_activity_date":1373117707,"creation_date":1373116204,"last_edit_date":1373117521,"question_id":17503294,"link":"https://stackoverflow.com/questions/17503294/php-two-way-merge-sort","title":"PHP two-way merge sort"},{"tags":["php","arrays","sorting","object","merge"],"owner":{"reputation":788,"user_id":1861766,"user_type":"registered","accept_rate":44,"profile_image":"https://www.gravatar.com/avatar/1af2b33383d9d6f83cd6616a9ad99a9e?s=128&d=identicon&r=PG","display_name":"ChuckKelly","link":"https://stackoverflow.com/users/1861766/chuckkelly"},"is_answered":true,"view_count":280,"accepted_answer_id":18881112,"answer_count":1,"score":0,"last_activity_date":1379537656,"creation_date":1379533036,"last_edit_date":1379533878,"question_id":18880844,"link":"https://stackoverflow.com/questions/18880844/php-merge-sort-several-different-arrays-of-objects","title":"PHP Merge & Sort Several Different Arrays of Objects"},{"tags":["php","python","mergesort"],"owner":{"reputation":3,"user_id":7216164,"user_type":"registered","profile_image":"https://www.gravatar.com/avatar/09ea0737f51fddf465a07cbf79611f92?s=128&d=identicon&r=PG&f=1","display_name":"BeMu","link":"https://stackoverflow.com/users/7216164/bemu"},"is_answered":true,"view_count":25,"accepted_answer_id":43169171,"answer_count":1,"score":-1,"last_activity_date":1491141362,"creation_date":1491140390,"question_id":43169004,"link":"https://stackoverflow.com/questions/43169004/php-merge-sort-not-working","title":"PHP merge sort not working"}],"has_more":false,"quota_max":300,"quota_remaining":299} --------------------------------------------------------------------------------