UNPKG

phpjs

Version:

php.js offers community built php functions in javascript

484 lines (442 loc) 14.5 kB
<!-- Generated by Rakefile:build --> <strong> <a href="http://kevin.vanzonneveld.net" rel="nofollow">Kevin van Zonneveld</a> </strong> on 2009-01-06 14:01:10 <br /> @ Brett Zamir: Nice dude :) <hr /> <strong> <a href="http://bahai-library.com" rel="nofollow">Brett Zamir</a> </strong> on 2009-01-01 03:50:27 <br /> By the way, I noticed now that there is a built-in way in JavaScript 1.7 to do the each() iteration: using Iterator() (and otherwise progress through arrays/objects). See https://developer.mozilla.org/en/New_in_JavaScript_1.7#Looping_across_objects and https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Iterators_and_Generators#Iterators Still, it shouldn't hurt to have them with the PHP equivalents (I think the PHP way is easier)... Brett <hr /> <strong> <a href="http://bahai-library.com" rel="nofollow">Brett Zamir</a> </strong> on 2009-01-01 03:28:57 <br /> Hi Kevin, I think I got it working now... Thanks for the offer... Although I don't drink (I'm a Baha'i), if I did drink, I'd be glad to have one with you... You seem like a most gracious person... Have a happy new year... And Onno too--thanks for keeping me on my toes, you guys... :) <pre><code>function pos (arr) { // Alias of current return current(arr); } function current (arr) { if (!window.php_js) window.php_js = {pointers:[]}; var pointers = window.php_js.pointers; if (pointers.indexOf(arr) === -1) { pointers.push(arr, 0); } var arrpos = pointers.indexOf(arr); var cursor = pointers[arrpos+1]; if (arr instanceof Array) { return arr[cursor] || false; } var ct = 0; for (var k in arr) { if (ct === cursor) { return arr[k]; } ct++; } return false; // Empty } function next (arr) { if (!window.php_js) window.php_js = {pointers:[]}; var pointers = window.php_js.pointers; if (pointers.indexOf(arr) === -1) { pointers.push(arr, 0); } var arrpos = pointers.indexOf(arr); var cursor = pointers[arrpos+1]; if (!(arr instanceof Array)) { var ct = 0; for (var k in arr) { if (ct === cursor+1) { pointers[arrpos+1] += 1; return arr[k]; } ct++; } return false; // End } if (arr.length === 0 || cursor === (arr.length-1)) { return false; } pointers[arrpos+1] += 1; return arr[pointers[arrpos+1]]; } function prev (arr) { if (!window.php_js) window.php_js = {pointers:[]}; var pointers = window.php_js.pointers; var arrpos = pointers.indexOf(arr); var cursor = pointers[arrpos+1]; if (pointers.indexOf(arr) === -1 || cursor === 0) { return false; } if (!(arr instanceof Array)) { var ct = 0; for (var k in arr) { if (ct === cursor-1) { pointers[arrpos+1] -= 1; return arr[k]; } ct++; } // Shouldn't reach here } if (arr.length === 0) { return false; } pointers[arrpos+1] -= 1; return arr[pointers[arrpos+1]]; } function reset (arr) { if (!window.php_js) window.php_js = {pointers:[]}; var pointers = window.php_js.pointers; if (pointers.indexOf(arr) === -1) { pointers.push(arr, 0); } var arrpos = pointers.indexOf(arr); if (!(arr instanceof Array)) { for (var k in arr) { if (pointers.indexOf(arr) === -1) { pointers.push(arr, 0); } else { pointers[arrpos+1] = 0; } return arr[k]; } return false; // Empty } if (arr.length === 0) { return false; } pointers[arrpos+1] = 0; return arr[pointers[arrpos+1]]; } function end (arr) { if (!window.php_js) window.php_js = {pointers:[]}; var pointers = window.php_js.pointers; if (pointers.indexOf(arr) === -1) { pointers.push(arr, 0); } var arrpos = pointers.indexOf(arr); if (!(arr instanceof Array)) { var ct = 0; for (var k in arr) { ct++; var val = arr[k]; } if (ct === 0) { return false; // Empty } pointers[arrpos+1] = ct - 1; return val; } if (arr.length === 0) { return false; } pointers[arrpos+1] = arr.length - 1; return arr[pointers[arrpos+1]]; } function key (arr) { if (!window.php_js) window.php_js = {pointers:[]}; var pointers = window.php_js.pointers; if (pointers.indexOf(arr) === -1) { pointers.push(arr, 0); } var cursor = pointers[pointers.indexOf(arr)+1]; if (!(arr instanceof Array)) { var ct = 0; for (var k in arr) { if (ct === cursor) { return k; } ct++; } return false; // Empty } if (arr.length === 0) { return false; } return cursor; } function each (arr) { // Will return a 4-item object unless a class property 'returnArrayOnly' is set to true on this function if want to only receive a two-item numerically-indexed array (for the sake of array destructuring in JavaScript 1.7+ (similar to list() in PHP, but as PHP does it automatically in that context and JavaScript cannot, we needed something to allow that option) // See https://developer.mozilla.org/en/New_in_JavaScript_1.7#Destructuring_assignment if (!window.php_js) window.php_js = {pointers:[]}; var pointers = window.php_js.pointers; if (pointers.indexOf(arr) === -1) { pointers.push(arr, 0); } var arrpos = pointers.indexOf(arr); var cursor = pointers[arrpos+1]; if (!(arr instanceof Array)) { var ct = 0; for (var k in arr) { if (ct === cursor) { pointers[arrpos+1] += 1; if (each.returnArrayOnly) { return [k, arr[k]]; } else { return {1:arr[k], value:arr[k], 0:k, key:k}; } } ct++; } return false; // Empty } if (arr.length === 0 || cursor === arr.length) { return false; } pos = cursor; pointers[arrpos+1] += 1; if (each.returnArrayOnly) { return [pos, arr[pos]]; } else { return {1:arr[pos], value:arr[pos], 0:pos, key:pos}; } } </code></pre> <hr /> <strong> <a href="http://kevin.vanzonneveld.net" rel="nofollow">Kevin van Zonneveld</a> </strong> on 2008-12-31 13:19:04 <br /> @ Brett Zamir: You're onto something there! I'm sure we'll work it out next year ;) Guys, best wishes and have a good one tonight. Have a drink from me will you? And let 2009 be a happy &amp;amp; successful year for you &amp;amp; your projects :) Regards! <hr /> <strong> <a href="http://bahai-library.com" rel="nofollow">Brett Zamir</a> </strong> on 2008-12-30 18:19:10 <br /> Yeah, that's a good point about serialization. Since we can't get unique memory addresses directly in JavaScript (thank heavens!) (and toSource() as an id would not distinguish between arrays with the same values), I think what we might try is to store their references directly (for the sake of later comparison) like this along with the key: <pre><code>var pointers = window.php_js.pointers; if (pointers.indexOf(arr) === -1) { pointers.push(arr, incrementVal); } else { pointers[pointers.indexOf(arr)+1] += incrementVal; // Or do whatever needed to be done } </code></pre> I'll try to look into that later (unless you're so inspired), as well as get back to you on the constants function... All the best... <hr /> <strong> <a href="http://kevin.vanzonneveld.net" rel="nofollow">Kevin van Zonneveld</a> </strong> on 2008-12-30 12:05:49 <br /> @ Brett Zamir: That's some hard labour there Brett. And it makes me smile that with these functions you could actually do this: <pre><code> reset($fruit); while ([$key, $val] = each($fruit)) { echo ($key +&amp;quot;:&amp;quot;+ $val+&amp;quot;\n&amp;quot;); } </code></pre> In JavaScript :) So kuddo's to you man. But (sorry, there always is a but) before adding, I do not feel comfortable storing the pointer inside the userobject. This may introduce the infamous Heisenbug. Imagine you have an important object that stores user information. You work on it using reset &amp;amp; each (you do not expect these to alter your data in any way), serialize it, and finally send it to the server. Now the serialized information will contain a strange element: '_phpjs_pos' that may lead to all kind of unexpected results. It may cause unaware developers some hard time debugging, and may (in some rare cases but still) even lead to server side data corruption. In short, this is not something I can willingly introduce to the project. I'd rather it be stored in the window.php_js global variable, as we already have such a mechanism for include_once. So we're not introducing additional dirt. I imagine something like: <pre><code> window.php_js.pointers[pointerId] = key; </code></pre> One challenge of that approach is that we'd have to figure out a way to add the scope to the so-called pointerId. But if we cannot overcome that I have some strong issues with adding these current implementations. Can you guys share this opinion? <hr /> <strong> Brett Zamir </strong> on 2008-12-20 17:59:02 <br /> While the above functioning works fine from what I can tell (besides not offering to return a regular array in circumstances as is useful with destructuring assignment in JavaScript 1.7), in order to maintain pointer state in a way which would work across all such functions (and also make the array key a little more &amp;quot;namespaced&amp;quot;), I rewrote each() as well as added all of the following functions. I hadn't thought about using a property on the array to preserve the pointer position until now, so I was mistaken in thinking it not possible to do this in JavaScript. ...Examples are adapted from the PHP manual...Note that the pointer property is not reset by other JavaScript actions as it might be in PHP (e.g., assigning an array to another variable). <pre><code>$foo = {&amp;quot;Robert&amp;quot; : &amp;quot;Bob&amp;quot;, &amp;quot;Seppo&amp;quot; : &amp;quot;Sepi&amp;quot;}; $bar = each($foo); var_dump($bar) $fruit = {'a' : 'apple', 'b' : 'banana', 'c' : 'cranberry'}; reset($fruit); while ([$key, $val] = each($fruit)) { alert( $key +&amp;quot;:&amp;quot;+ $val+&amp;quot;\n&amp;quot;); } $transport = new Array('foot', 'bike', 'car', 'plane'); // $transport = {a:2, b:3}; // Tried also with this $mode = current($transport); // $mode = 'foot'; $mode = next($transport); // $mode = 'bike'; $mode = current($transport); // $mode = 'bike'; $mode = prev($transport); // $mode = 'foot'; $mode = end($transport); // $mode = 'plane'; $mode = current($transport); // $mode = 'plane'; $arr = []; var_dump(current($arr)); // bool(false) $arr = new Array([]); var_dump(current($arr)); // array(0) { } function pos (arr) { // Alias of current return current(arr); } function current (arr) { if (!arr._phpjs_pos) { arr._phpjs_pos = 0; } if (arr instanceof Array) { return arr[arr._phpjs_pos] || false; } var ct = 0; for (var k in arr) { if (k !== '_phpjs_pos') { if (ct === arr._phpjs_pos) { return arr[k]; } ct++; } } return false; // Empty } function next (arr) { if (!arr._phpjs_pos) { arr._phpjs_pos = 0; } if (!(arr instanceof Array)) { var ct = 0; for (var k in arr) { if (k !== '_phpjs_pos') { if (ct === arr._phpjs_pos+1) { arr._phpjs_pos += 1; return arr[k]; } ct++; } } return false; // End } if (arr.length === 0 || arr._phpjs_pos === (arr.length-1)) { return false; } arr._phpjs_pos += 1; return arr[arr._phpjs_pos]; } function prev (arr) { if (arr._phpjs_pos === 0 || arr._phpjs_pos === undefined) { return false; } if (!(arr instanceof Array)) { var ct = 0; for (var k in arr) { if (k !== '_phpjs_pos') { if (ct === arr._phpjs_pos-1) { arr._phpjs_pos -= 1; return arr[k]; } ct++; } } // Shouldn't reach here } if (arr.length === 0) { return false; } arr._phpjs_pos -= 1; return arr[arr._phpjs_pos]; } function reset (arr) { if (!(arr instanceof Array)) { for (var k in arr) { if (k !== '_phpjs_pos') { arr._phpjs_pos = 0; return arr[k]; } } return false; // Empty } if (arr.length === 0) { return false; } arr._phpjs_pos = 0; return arr[arr._phpjs_pos]; } function end (arr) { if (!(arr instanceof Array)) { var ct = 0; for (var k in arr) { if (k !== '_phpjs_pos') { ct++; var val = arr[k]; } } if (ct === 0) { return false; // Empty } arr._phpjs_pos = ct - 1; return val; } if (arr.length === 0) { return false; } arr._phpjs_pos = arr.length - 1; return arr[arr._phpjs_pos]; } function key (arr) { if (!arr._phpjs_pos) { arr._phpjs_pos = 0; } if (!(arr instanceof Array)) { var ct = 0; for (var k in arr) { if (k !== '_phpjs_pos') { if (ct === arr._phpjs_pos) { return k; } ct++; } } return false; // Empty } if (arr.length === 0) { // Todo: verify this is result (and return false just above) return false; } return arr._phpjs_pos !== undefined ? arr._phpjs_pos : 0; } function each (arr) { // Will return a 4-item object unless a class property 'returnArrayOnly' is set to true on this function if want to only receive a two-item numerically-indexed array (for the sake of array destructuring in JavaScript 1.7+ (similar to list() in PHP, but as PHP does it automatically in that context and JavaScript cannot, we needed something to allow that option) // See https://developer.mozilla.org/en/New_in_JavaScript_1.7#Destructuring_assignment if (!arr._phpjs_pos) { arr._phpjs_pos = 0; } if (!(arr instanceof Array)) { var ct = 0; for (var k in arr) { if (k !== '_phpjs_pos') { if (ct === arr._phpjs_pos) { arr._phpjs_pos += 1; if (each.returnArrayOnly) { return [k, arr[k]]; } else { return {1:arr[k], value:arr[k], 0:k, key:k}; } } ct++; } } return false; // Empty } if (arr.length === 0 || arr._phpjs_pos === arr.length) { return false; } pos = arr._phpjs_pos; arr._phpjs_pos += 1; if (each.returnArrayOnly) { return [pos, arr[pos]]; } else { return {1:arr[pos], value:arr[pos], 0:pos, key:pos}; } } </code></pre> <hr />