How is it possible that whereNotIn() plus whereIn() doesn't equal total count?
Running this:
$updatedBreeds = [
86,
113,
// etc ....
];
DB::enableQueryLog();
dump(Breed::count());
dump(Breed::whereIn('id', $updatedBreeds)->count());
dump(Breed::whereNotIn('id', $updatedBreeds)->count());
dd(DB::getQueryLog());
Returns this:
159
39
0
Am I missing something here? The whereNotIn() call should return 120 results.
Apparently, one of the values in the array was null. Which strangely enough led to this behavior.
Here is a dump on $updatedBreeds:
[
0 => 86
1 => 113
- 2 => null // When I removed this value, the whereNotIn() worked
2 => 44
3 => 8
4 => 54
5 => 54
// ...
]
### Result of sort
sort($keys_arranged, SORT_NUMERIC);
var_dump($keys_arranged);
{ ...
[51]=> float(11.903327742296)
[52]=> int(5)
[53]=> float(13.165002546636)
[54]=> float(14.478273306964)
[55]=> float(4.6264742674547)
[56]=> float(13.290508819344)
[57]=> float(15.686809055276) }
### Result or rsort
rsort($keys_arranged, SORT_NUMERIC);
var_dump($keys_arranged);
{
[0]=> float(15.686809055276)
[1]=> float(14.478273306964)
[2]=> float(13.290508819344)
[3]=> float(13.165002546636)
[4]=> float(11.903327742296)
[5]=> int(5)
[6]=> float(4.6264742674547)
... }
echo var_export($keys_arranged);
array ( 0 => 3.142678516658294, 1 => 1.0, 2 => 1.0, 3 => 14.478273306963985, 4 => 13.165002546635966, 5 => 1.0, 6 => 1.0005037081114851, 7 => 1.0, 8 => 4.6264742674547001, 9 => 15.686809055275578, 10 => 1.0, 11 => 11.903327742295504, 12 => 13.29050881934397, 13 => 1.0, 14 => 1.0, 15 => 3.5421134937189365, 16 => 1.0, 17 => 0.010999999999999999, 18 => 3.2999566681750605, 19 => 5, 20 => 1.2282984802843129, 21 => 1.0, 22 => 2.9748253120971184, 23 => 0.44855992975075798, 24 => 0.99999999999999989, 25 => 3.8350475954623371, 26 => 1.0625975061426283, 27 => 1.0000072792091179, 28 => 0.99999987785487132, 29 => 1, 30 => 0.0, 31 => 1.0, 32 => 1.0, 33 => 1.0, 34 => 0.0, 35 => 1.0972568578553616, 36 => 1.0, 37 => 1.4077661823957415, 38 => 1.0, 39 => 0.0, 40 => 3.6038030347555705, 41 => 1.0, 42 => 1.0, 43 => 1.0636876768842174, 44 => 1.0, 45 => NAN, 46 => 1.0, 47 => NAN, 48 => NAN, 49 => NAN, 50 => NAN, 51 => 1.0, 52 => 1.0, 53 => NAN, 54 => 0.99958680716631509, 55 => 1.0, 56 => NAN, 57 => 1.0, )
I got some incorrect result from array_multisort. It has 8 different keys and all the keys but this key(say A) works fine.
To figure out why that happened, I played with A in the array. And I could see that not only in the function of array_multisort, but also in 'sort' function, an incorrect result prompted as well.
As you can see the result of rsort seems okay, the result of sort works strangely when it comes to
13.16 < 14.47 < 4.62 < 13.29 < 15.68
Does anyone know why this occurred?
// Data in readible format
array (
0 => 3.142678516658294,
1 => 1.0,
2 => 1.0,
3 => 14.478273306963985,
4 => 13.165002546635966,
5 => 1.0,
6 => 1.0005037081114851,
7 => 1.0,
8 => 4.6264742674547001,
9 => 15.686809055275578,
10 => 1.0,
11 => 11.903327742295504,
12 => 13.29050881934397,
13 => 1.0,
14 => 1.0,
15 => 3.5421134937189365,
16 => 1.0,
17 => 0.010999999999999999,
18 => 3.2999566681750605,
19 => 5,
20 => 1.2282984802843129,
21 => 1.0,
22 => 2.9748253120971184,
23 => 0.44855992975075798,
24 => 0.99999999999999989,
25 => 3.8350475954623371,
26 => 1.0625975061426283,
27 => 1.0000072792091179,
28 => 0.99999987785487132,
29 => 1,
30 => 0.0,
31 => 1.0,
32 => 1.0,
33 => 1.0,
34 => 0.0,
35 => 1.0972568578553616,
36 => 1.0,
37 => 1.4077661823957415,
38 => 1.0,
39 => 0.0,
40 => 3.6038030347555705,
41 => 1.0,
42 => 1.0,
43 => 1.0636876768842174,
44 => 1.0,
45 => NAN,
46 => 1.0,
47 => NAN,
48 => NAN,
49 => NAN,
50 => NAN,
51 => 1.0,
52 => 1.0,
53 => NAN,
54 => 0.99958680716631509,
55 => 1.0,
56 => NAN,
57 => 1.0, )
It seems as you actually do have discovered a bug. On large arrays containing NaN values, represented by the NAN constant in PHP, the built-in function sort fails.
The comparision with NaN should always result as non-ordered as mentioned by kuh-chan in the question comments. However, as soon as there is at least one operand NaN, in recent (March 2019) versions of PHP the spaceship operator <=> returns 1 (first operand greater than second one) and -1 (first operand less than second one) in some other versions.
echo var_dump( NAN <=> 1.23 );
echo var_dump( 1.23 <=> NAN );
echo var_dump( NAN <=> -1.23 );
echo var_dump( -1.23 <=> NAN );
echo var_dump( NAN <=> 0 );
echo var_dump( NAN <=> NAN );
I'm not very famimilar with the internals of the Zend engine. However, I guess the sort algorithm terminates too soon on large arrays with several NaN values, likely in order to the order comparision algorithm alway returns "greater (or less) than" which probably leads to multiple exchanges of the same elements.
I experienced that calling sort multiple times seems to continue the sorting. However, that would not be a proper workaround.
You can use a custom comparision algorithm with usort instead. If you want to order NaN at the start of the array, return -1 when the first operand is NaN, 1 when the second operand is NaN and 0 (equal) if both are. Otherwise return the comparision result of the spaceship operator.
usort($keys_arranged,
function(&$v1, &$v2)
{
switch( (is_nan($v1) ? 1 : 0) | (is_nan($v2) ? 2 : 0) )
{
case 0: return $v1 <=> $v2;
case 1: return -1;
case 2: return 1;
case 3: return 0;
}
}
);
Similar bitwise logic as above, but in a more compressive and direct form:
usort( $keys_arranged,
function(&$v1, &$v2){ return -2 === ($b = (is_nan($v1) ? -1 : -2) ^ (is_nan($v2) ? -1 : 0)) ? $v1 <=> $v2 : $b; }
);
I have two MySQL tables, one is called "version" and the other is called "lines" inside one DB called "project".
The "version" table consist of:
id (PRIMARY / AI) = int
version = string
Rows:
# | version
------------
0 | 100
1 | 200
3 | 400
The "lines" table consist of:
id (PRIMARY / AI) = int
lines = string
version_id = string (ID from table version)
Rows:
# | line | version_id
--------------------------
0 | line #1 | 0
1 | line #2 | 0
2 | line #3 | 1
3 | line #4 | 0
4 | line #5 | 1
How can I create multidimensional array to output an example JSON (pseudo)
"full" =>
"version" => "100"
"id" => "0", (version id table)
"line" =>
"row_0" => "line #1", (from lines table)
"row_1" => "line #2",
"row_2" => "line #4",
"version" => "200"
"id" => "1",
"line" =>
"row_0" => "line #3",
"row_1" => "line #5",
"version" => "300"
"id" => "3",
"line" => "EMPTY" (no lines for this version)
]
I rewrote the code a couple of times but I can't make it work. Either I stuck or I finish in infinite loop of errors. This is what I got for now:
function returnJson() {
$db = DB::query("SELECT * FROM version");
foreach ($db as $row) {
$i++;
$lines = DB::Query("SELECT * FROM lines WHERE version_id=%i", $row['id']);
// approach to nested array?
}
}
I'm using MeekroDB so any approach to MySQL is offset. You can write an example in PDO if you are more familiar with it.
I assume that the array you want would look like this in php:
"full" =>
"100" => array (
"versionId" => "0", (version id table)
"line" =>
"row_0" => "line #1", (
"row_1" => "line #2",
"row_2" => "line #4"
)
, "200" => array (
"versionId" => "1",
"line" => array (
"row_0" => "line #3",
"row_1" => "line #5" )
)
, "300" => array (
"versionId" => "3",
"line" => array()
)
]
Use a JOIN
SELECT v.id AS versionId, v.version l.id as linesId, l.lines
FROM version v
INNER JOIN lines l ON v.id = l.version_id
And then a loop with some if statement to build the array
$versions = array();
foreach($db as $row) {
if (!isset($versions[$db["version"]]))
$versions[$db["version"]] = array (
"versionId" => $db["versionId"],
"line" => array()
);
if (!empty($db["lines"]))
$versions[$db["version"]][lines"][] = $db["lines"];
}
Try the accepted answer in this SO post which also deals with nested JSON data.
Also you may want to reduce your SQL to below and just use one loop instead of 2 nested loops as in the SO post above.
SELECT *
FROM version
INNER
JOIN lines
ON version.id = lines.version_id
Hope this helps.
so i have a bit difficulty in combining arrays in php. So let say i have these 2 array
array:4 [▼
20 => "University"
21 => "Polic Station"
22 => "Ambulance"
1 => "Zoo"
]
array:4 [▼
20 => "abc"
21 => "def"
22 => "ghi"
1 => "jkl"
]
How do i actually combine this to this
array:4 [▼
20 => "abc University"
21 => "def Polic Station"
22 => "ghi Ambulance"
1 => "jkl Zoo"
]
Here's the result:
$arr = array(
20=>'University',
21=>'Polic Station',
22=>'Ambulance',
1=>'Zoo');
$arr2= array(
20=>'abc',
21=>'def',
22=>'ghi',
1=>'jkl');
$arr_out = array();
foreach($arr as $key=>$el) {
$arr_out[$key] = $arr2[$key] ." ".$el;
}
var_dump($arr_out);
Obviously, you'll need to keep in mind to check whether the key exists in the second array so you do not get an error when accessing the value.
i installed a project edusec school management system which work on php mysql yii framework.but when we copy it root directory and run index.php on local server it give following error ? what i do ??please help me?
PHP warning
Invalid argument supplied for foreach()
C:\xampp\htdocs\yiitest\protected\yii\framework\collections\CMap.php(288)
276 * #param array $b array to be merged from. You can specifiy additional
277 * arrays via third argument, fourth argument etc.
278 * #return array the merged array (the original arrays are not changed.)
279 * #see mergeWith
280 */
281 public static function mergeArray($a,$b)
282 {
283 $args=func_get_args();
284 $res=array_shift($args);
285 while(!empty($args))
286 {
287 $next=array_shift($args);
288 foreach($next as $k => $v)
289 {
290 if(is_integer($k))
291 isset($res[$k]) ? $res[]=$v : $res[$k]=$v;
292 else if(is_array($v) && isset($res[$k]) && is_array($res[$k]))
293 $res[$k]=self::mergeArray($res[$k],$v);
294 else
295 $res[$k]=$v;
296 }
297 }
298 return $res;
299 }
300
Stack Trace
#0
– C:\xampp\htdocs\yiitest\protected\yii\framework\base\CModule.php(468): CMap::mergeArray(array("class" => "CDbConnection"), 1)
463 foreach($components as $id=>$component)
464 {
465 if($component instanceof IApplicationComponent)
466 $this->setComponent($id,$component);
467 else if(isset($this->_componentConfig[$id]) && $merge)
468 $this->_componentConfig[$id]=CMap::mergeArray($this->_componentConfig[$id],$component);
469 else
470 $this->_componentConfig[$id]=$component;
471 }
472 }
473
#1
+ C:\xampp\htdocs\yiitest\protected\yii\framework\base\CComponent.php(153): CModule->setComponents(array("user" => array("allowAutoLogin" => true, "class" => "RWebUser"), "phpThumb" => array("class" => "ext.EPhpThumb.EPhpThumb"), "authManager" => array("class" => "RDbAuthManager"), "urlManager" => array("urlFormat" => "path", "rules" => array("<controller:\w+>/<id:\d+>" => "<controller>/view", "<controller:\w+>/<action:\w+>/<id:\d+>" => "<controller>/<action>", "<controller:\w+>/<action:\w+>" => "<controller>/<action>")), ...))
#2
+ C:\xampp\htdocs\yiitest\protected\yii\framework\base\CModule.php(483): CComponent->__set("components", array("user" => array("allowAutoLogin" => true, "class" => "RWebUser"), "phpThumb" => array("class" => "ext.EPhpThumb.EPhpThumb"), "authManager" => array("class" => "RDbAuthManager"), "urlManager" => array("urlFormat" => "path", "rules" => array("<controller:\w+>/<id:\d+>" => "<controller>/view", "<controller:\w+>/<action:\w+>/<id:\d+>" => "<controller>/<action>", "<controller:\w+>/<action:\w+>" => "<controller>/<action>")), ...))
#3
+ C:\xampp\htdocs\yiitest\protected\yii\framework\base\CApplication.php(144): CModule->configure(array("name" => "College Management System", "preload" => array("log"), "import" => array("application.models.*", "application.extensions.jtogglecolumn.*", "application.extensions.AjaxList.AjaxList", "application.components.*", ...), "modules" => array("gii" => array("class" => "system.gii.GiiModule", "password" => "secure", "generatorPaths" => array("ext.gii-extended"), "ipFilters" => array("127.0.0.1", "::1", "192.168.0.163")), 0 => "notification", 1 => "webservice", "rights" => array("install" => false, "superuserName" => "SuperAdmin", "authenticatedName" => "Authenticated", "userIdColumn" => "user_id", ...), ...), ...))
#4
+ C:\xampp\htdocs\yiitest\protected\yii\framework\YiiBase.php(127): CApplication->__construct("C:\xampp\htdocs\yiitest/protected/config/main.php")
#5
+ C:\xampp\htdocs\yiitest\protected\yii\framework\YiiBase.php(100): YiiBase::createApplication("CWebApplication", "C:\xampp\htdocs\yiitest/protected/config/main.php")
#6
– C:\xampp\htdocs\yiitest\index.php(18): YiiBase::createWebApplication("C:\xampp\htdocs\yiitest/protected/config/main.php")
13
14 // specify how many levels of call stack should be shown in each log message
15 defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL',3);
16
17 require_once($yii);
18 Yii::createWebApplication($config)->run();
19 ?>
20
The function array_shift() at line 287 has returned null, so $next is not an array.
And of course foreach() requires an array.
Validate the value before passing into the loop. This will catch when the array is empty.
$next=array_shift($args);
if ($next != null)
{
foreach($next as $k => $v)
{
// do things here
}
}