php vfsStream is not parsing newline characters - php

I'm trying to unit test methods in isolation that work with csv files, using vsf-stream from here: https://github.com/mikey179/vfsStream
I've created a 2 dimensional data array to test, but when I try to add this to the mocked file it seems to parse the newline characters, instead of adding new lines. I've tried both fputcsv and fputs but both have the same results. Using the same data and php functions I can write successfully to a normal file, the issues seems to be with vfs-stream. Not much documentation on the net and completely lost:
$this->data = array(
array( 'col1', 'col2', 'col3', 'col4' ),
array( 'row 0 1', 'row 0 2', ' row 0 3', ' row 0 4' ),
array( 'row 1 1', 'row 1 2', ' row 1 3', ' row 1 4' ),
array( 'row 2 1', 'row 2 2', ' row 2 3', ' row 2 4' ),
array( 'row 3 1', 'row 3 2', ' row 3 3', ' row 3 4' ),
array( 'row 4 1', 'row 4 2', ' row 4 3', ' row 4 4' ),
array( 'row 5 1', 'row 5 2', ' row 5 3', ' row 5 4' ),
);
$this->root = vfsStream::setup('test-dir');
$file = vfsStream::url('test-dir/foo.csv');
$handle = fopen($file, "a+");
foreach( $this->data as $arr)
fputcsv($handle, $arr, "|"); //$content .= implode("|", $arr) . "\n";
The above code will produce the mocked file but without any newline characters, so parsing the mocked csv file later in the test won't work as it seems to all be written in the one long line:
var_dump( file_get_contents( $file ) );
will produce:
string(272) "col1|col2|col3|col4\n"row 0 1"|"row 0 2"|" row 0 3"|" row 0 4"\n"row 1 1"|"row 1 2"|" row 1 3"|" row 1 4"\n"row 2 1"|"row 2 2"|" row 2 3"|" row 2 4"\n"row 3 1"|"row 3 2"|" row 3 3"|" row 3 4"\n"row 4 1"|"row 4 2"|" row 4 3"|" row 4 4"\n"row 5 1"|"row 5 2"|" row 5 3"|" row 5 4"\n"
I'm hoping that I'm missing a flag for this and its not a bug. Any help appreciated, cheers.

The issue was using var_dump instead of print or echo to see the results. var_dump will give a descriptive and literal representation of the variable and not parse the \n chars - print or echo would print and parse the \n chars.
Therefore the above code works and its my stupidity or lack of sleep that is the issue.

Related

Restructure array from sql query so that I can echo proper values

I'm trying to get the content I need from a joined query and properly use values as an array key so that I can build some DIV lists properly
My php query and array:
$getTickers = "
SELECT d.ID as displayID, d.display_name as display, l.location_name as locationName, d.location_id as location, t.id as ticker, tc.id as contentID, tc.content
FROM displays d
INNER JOIN locations l on d.location_id = l.id
INNER JOIN tickers t on d.id = t.display_id
INNER JOIN ticker_content tc on t.id = tc.ticker_id;
";
$tickers = $mysqlConn->query($getTickers);
$tickerDisplays = array();
foreach($tickers as $subArray) {
if(!array_key_exists($subArray['displayID'], $tickerDisplays)) {
$tickerDisplays[$subArray['displayID']] = array();
}
// here you add `display_name` under key `display_id`
$tickerDisplays[$subArray['displayID']][$subArray['location']] = $subArray['display'];
}
All examples and code below, but I don't need the html structure help with this, just how to restructure the array/key to give me the desired results and how I should loop them on the front end.
I'm getting 4 divs as I expect right now (one for each unique display/location)
but I need to figure out how to correcty arrange it so I can echo the DIsplay name as the h4, the location as h5, and then each content in my list
So the query result gives me this:
displayID | display | locationName | location | ticker | contentID | content |
1 Office Building 4 4 1 1 testing content
2 Lobby Building 4 4 2 2 testing content 2
3 Lobby Building 1 1 3 3 testing content 3
4 Office Building 1 1 4 4 testing content 4
4 Office Building 1 1 4 5 testing content again
I'm trying to loop on this with the expected result of having a a div for each location/display combo like so:
OFFICE
Building 4
testing content
---------------
LOBBY
Building 4
testing content 2
------------------
LOBBY
Building 1
testing content 3
------------------
OFFICE
Building 1
testing content 4
testing content again
----------------------
Here's the way I'm currently trying to loop that
<?php foreach($tickerDisplays as $key => $ticker):?>
<h4><?php echo $key ?></h4> //so this should be the display Name (office, lobby)
<h5><?php echo //location?></h5> //this should be the location name (Building 1, Building 4)
//This will be another foreach for any content associated with the location/display
<ul class="tickerContent">
<li>
</ul>
</div>
</div>
<?php endforeach;?>
The approach here is to make a child array for each display line to contain all
the multiple content records.
// Dummy the data from the query
$tickers = [
['displayID' => 1, 'display' => 'Office', 'locationName' => 'Building 4', 'location' => 4, 'ticker' => 1, 'contentID' => 1, 'content' => 'testing content'],
['displayID' => 2, 'display' => 'Lobby', 'locationName' => 'Building 4', 'location' => 4, 'ticker' => 2, 'contentID' => 2, 'content' => 'testing content 2'],
['displayID' => 3, 'display' => 'Lobby', 'locationName' => 'Building 1', 'location' => 1, 'ticker' => 3, 'contentID' => 3, 'content' => 'testing content 3'],
['displayID' => 4, 'display' => 'Office', 'locationName' => 'Building 1', 'location' => 1, 'ticker' => 4, 'contentID' => 4, 'content' => 'testing content 4'],
['displayID' => 4, 'display' => 'Office', 'locationName' => 'Building 1', 'location' => 1, 'ticker' => 4, 'contentID' => 5, 'content' => 'testing content again']
];
// A place to keep the reorganized data
$tickerDisplays = [];
// Walk through the query result
foreach($tickers as $row) {
$displayID = $row['displayID']; // for convenience and readability
$location = $row['location']; // for convenience and readability
$display = $row['display'];
$contentID = $row['contentID'];
if ( ! array_key_exists($row['displayID'], $tickerDisplays) ) {
$tickerDisplays[$displayID] = [
'displayID' => $row['displayID'],
'display' => $row['display'],
'ticker' => $row['ticker'],
'contentID' => $row['contentID'],
'content' => $row['content'],
'location' => $row['location'],
'locationName' => $row['locationName'],
'#content' => [] // to store the content data
];
}
$tickerDisplays[$displayID]['#content'][$contentID] = ['content' => $row['content']];
}
print_r($tickerDisplays);
foreach ( $tickerDisplays as $key => $ticker ) {
// Output the display and location name
out($ticker['display']);
out($ticker['locationName']);
// Output all the content records.
foreach ( $ticker['#content'] as $contentID => $content ) {
out($content['content']);
}
out('------------');
}
// Just a utility function
function out($msg) {
echo "$msg\n";
}
Output:
Office
Building 4
testing content
------------
Lobby
Building 4
testing content 2
------------
Lobby
Building 1
testing content 3
------------
Office
Building 1
testing content 4
testing content again
------------

php - curl query to backend, mix up data

I'm not sure if this question was asked before, but I couldn't find anything.
When I CURL to the back-end from the front-end, I pass a JSON object containing a SQL query in base64:
base64(SELECT * FROM mytable) -> U0VMRUNUICogRlJPTSBteXRhYmxl
[{
'sql' : 'U0VMRUNUICogRlJPTSBteXRhYmxl'
}]
Back-end receives it, and then run that query over a sqlite3 database. It returns the data and put it into a JSON object:
[{
'column 1' : 'row 1 - data',
'column 2' : 'row 1 - data',
'column 3' : 'row 1 - data',
},{
'column 1' : 'row 2 - data',
'column 2' : 'row 2 - data',
'column 3' : 'row 2 - data',
},{
'column 1' : 'row 3 - data',
'column 2' : 'row 3 - data',
'column 3' : 'row 3 - data',
}]
and then returns it back with python flask server, I think with requests library.
My problem is that the JSON object that comes back doesn't look like the one above, but returns more like:
[{
'column 2' : 'row 1 - data',
'column 3' : 'row 1 - data',
'column 1' : 'row 1 - data',
},{
'column 2' : 'row 2 - data',
'column 3' : 'row 2 - data',
'column 1' : 'row 2 - data',
},{
'column 2' : 'row 3 - data',
'column 3' : 'row 3 - data',
'column 1' : 'row 3 - data',
}]
and I don't know why. I even tried to specify the SELECT statement as
SELECT "column 1", "column 2", "column 3" FROM mytable;
but still the same.
I can order it myself, but there isn't only 1 table to be queried.
My CURL code:
$query = $_POST['query'];
function safeQ($squery){
$denied = ["update","delete","insert","create","alter","drop"];
$squery = strtolower($squery);
foreach($denied as &$deny){
if (strpos($squery, $deny) !== false) {
return false;
}
}
return true;
}
print(getQuery($query));
function getQuery($query){
if (safeQ($query)){
$data->sql = base64_encode($query);
$jsonData = json_encode($data);
$ch = curl_init('https://www.example.com/api/sql_query');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($jsonData))
);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return $result;
}
}
To answer your question why, it is the same thing I said in the comments; when python is storing a dictionary, it does not care about order. Why the order turns out the way it does? That requires a more complicated knowledge of memory allocation that i'm currently capable of answering, but the point of using a key/value structure is not regarding the order the entries are in.
[{
'column 2' : 'row 1 - data',
'column 3' : 'row 1 - data',
'column 1' : 'row 1 - data',
},{
'column 2' : 'row 2 - data',
'column 3' : 'row 2 - data',
'column 1' : 'row 2 - data',
},{
'column 2' : 'row 3 - data',
'column 3' : 'row 3 - data',
'column 1' : 'row 3 - data',
}]
Is completely fine. If you start seeing this however;
[{
'column 2' : 'row 1 - data',
'column 3' : 'row 1 - data',
'column 1' : 'row 1 - data',
},{
'column 2' : 'row 3 - data',
'column 3' : 'row 3 - data',
'column 1' : 'row 3 - data',
},{
'column 2' : 'row 2 - data',
'column 3' : 'row 2 - data',
'column 1' : 'row 2 - data',
}]
It is a case for concern, since this time the array type structure got out of its original order.
You can make the following assertion yourself by opening an interpreter
>>> {'a':1,'b':2} == {'b':2,'a':1}
True

Add integers to duplicate values in array [duplicate]

This question already has answers here:
PHP: How to identify AND CHANGE duplicate values in an array?
(2 answers)
Closed 7 years ago.
How do I go about getting all of the duplicate values in an array, and assigning an integer to each of them to make them unique. For example:
array(
0 => 'Title',
1 => 'Primary Contact: Name',
2 => 'Primary Contact: Email',
3 = > 'Title',
4 = > 'Title'
);
My goal is to turn that into the following:
array(
0 => 'Title - 1',
1 => 'Primary Contact: Name',
2 => 'Primary Contact: Email',
3 = > 'Title - 2',
4 = > 'Title - 3'
);
You could use a foreach to integrate through the array and use array_keys with the search option to check for the value in the array and update it.
http://php.net/manual/en/function.array-keys.php

Yii: can't use LIMIT in a mysql query

I'm using Yii, and I want to select 5 rows from mysql starting from the third row.
For Example, I have these rows:
ID - NAME
1 - abc
2 - bcd
3 - hdf
4 - fgr
5 - gdf
...
and I want to select 5 rows, starting from the third row.
My code:
$rows = Users::model()->findAll(array(
'order' => 'id DESC',
'limit' => '3, 5'
));
The problem this selects nothing.
There is an offset parameter.
$rows = Users::model()->findAll(array(
'order' => 'id DESC',
'limit' => '5',
'offset' => '3'
));

Mysql Update mutiple row of datas

I would like to know how to efficiently update multiple rows of data with the UPDATE statement. I know I can insert multiple records like this one below.
INSERT INTO example
(example_id, name, value, other_value)
VALUES
(100, 'Name 1', 'Value 1', 'Other 1'),
(101, 'Name 2', 'Value 2', 'Other 2'),
(102, 'Name 3', 'Value 3', 'Other 3'),
(103, 'Name 4', 'Value 4', 'Other 4');
But how it works in Update, or if I have to loop the query and update one by one?
At the moment I have to use foreach to loop and update each SQL statement.
foreach() {
// update statement....
// and execute the query
}
You can use case when indise update..
An eg:
UPDATE users
SET value = CASE
WHEN id in (1,4) THEN 53
WHEN id = 2 THEN 65
WHEN id in (3,5) THEN 47
END
WHERE id IN (1,2,3,4,5)
Refer this so and this for more.
$data = array(
array(
100,
'Name 1',
'Value 1',
'Other 1'
),
array(
101,
'Name 2',
'Value 2',
'Other 2',
)
array(
102,
'Name 3',
'Value 3',
'Other 3'
)
)
for($i = 0; $i < count($data); $i++) {
for($j= 0; $j< count($data[$i]); $j++) {
$field1 = $data[$i][$j];
$field2 = $data[$i][$j];
$filed3 = $data[$i][$j];
$field4 = $data[$i][$j];
query("UPDATE TABLE SET.... WHERE id = $field1");
}
}
You can use CASE in MYSQL also:
Ex:
UPDATE example
SET example_id = CASE
WHEN example_id=100 THEN 1000
WHEN example_id=101 THEN 1001
WHEN example_id=102 THEN 1002
ELSE example_id*10
END
You can see another example, In this, there is a table Person and having wrongly entered Gender. So you need to correct them by updating Male to Female and Female to Male.
So here is your code:
UPDATE Person
SET Gender= CASE
WHEN gender= 'Male' THEN 'Female'
WHEN gender= 'Female' THEN 'Male'
ELSE gender
END

Categories