Box/Spout questions - php

This is my first time using Box/Spout library. I am using WAMP server.
My question is the following:
require_once('./spout-master/src/Spout/Autoloader/autoload.php');
use Box\Spout\Writer\WriterFactory;
use Box\Spout\Common\Type;
$filePath = 'test.xlsx';
$writer = WriterFactory::create(Type::XLSX);
$writer->openToFile($filePath);
[X]
$writer->addRow(['a'], $style);
$writer->close();
(1)
When I am running above code, I get the following error message:
Warning: rmdir(C:\WINDOWS\TEMP/xlsx560f58d588ceb): Permission denied in
C:\wamp\www\1300.revenue.com.my\public_html\spoutmaster\src\Spout\Common\Helper\FileSystemHelper.php on line 113
What is the errors means and how should I modify it to prevent this error message appeared?
(2) I want to make expected output like below:
But I didn't know how to write it on [X] part. How to write it in order to get the expected output?

It looks like the default temp folder used to generate the XLSX file cannot be deleted. You can verify it by checking the permissions on C:\WINDOWS\TEMP/xlsx560f58d588ceb.
To solve this issue, you can either manually fix the permissions on the temp folder (C:\WINDOWS\TEMP) or use another temporary folder, as specified here: https://github.com/box/spout#using-custom-temporary-folder
Regarding 2), there is no straightforward way to do this whith Spout. Spout does not support merging cells. The only thing you can do is:
| 1 | 2 | | 3 | |
|---|---|---|---|---|
| | A | B | A | B |
|---|---|---|---|---|
Or alternatively (if that makes more sense):
| 1 | 2 | 2 | 3 | 3 |
|---|---|---|---|---|
| 1 | A | B | A | B |
|---|---|---|---|---|
Either way, you'll have to format the rows as shown above: [[1,2,'',3',''], ['', 'A','B','A','B']] or [[1,2,2,3,3], [1, 'A','B','A','B']]

Related

Sphinx: PDO exception with certain characters

I'm trying to get the Sphinx search server working with PDO, but it triggers a syntax error when using the MATCH() function in specific scenarios.
Ex.:
In my code I'm splitting the search query by space and then concatenate it using the | (OR) operator. If someone types test > 3, in the match function it would become (test | > | 3). This combination triggers a: Syntax error or access violation: 1064 main_idx: syntax error, unexpected '|' near ' > | 3'. I don't think it's an escape problem because the > character is not on the escape list and even if you try to escape it, it doesn't work. Is this a bug in the version of Sphinx i'm using? Or am I doing something wrong?
I'm using Sphinx version 2.2.11. It's actually a docker instance provided by this image: jamesrwhite/sphinx-alpine:2.2.11
The PHP version is 7.2.
This is my non-working code:
$searchQuery = "SELECT * FROM main_idx WHERE MATCH(:search)";
$dbh = new PDO('mysql:host=127.0.0.1;port=9306', 'root', 'root');
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $dbh->prepare($searchQuery);
$stmt->bindValue('search', 'test | > | 3');
$stmt->execute();
Same code works perfectly fine if I'm using the MySQLi extension. It also works fine with PDO and Sphinx version 2.2.6. Something must've changed between 2.2.6 and 2.2.11. Anyone encountered this issue?
This behaviour is caused by this bug http://sphinxsearch.com/bugs/view.php?id=2305 and this fix https://github.com/sphinxsearch/sphinx/commit/d9923f76c7724fa8d05a3d328e26a664799841b7. In the previous revision ' > | ' was supported.
We at Manticore Search (fork of Sphinx) will check if the fix was correct and will make a better fix if that's not. Thanks for pointing this out.
Meanwhile you can use 2.2.8 from http://sphinxsearch.com/downloads/archive/ or build manually from the latest revision which supports the syntax (https://github.com/sphinxsearch/sphinx/commit/f33fa667fbfd2031ff072354ade4b050649fbd4e)
[UPDATE]
The fix is proper. It was wrong to not show the error about that in the previous versions as long as you DON'T have the spec. character (>) in your charset_table. To workaround this you can add > to your charset_table and then escape it in the search query, e.g.:
mysql> select * from idx_min where match('test | \\> | a');
+------+---------+----------+-------+------+
| id | doc | group_id | color | size |
+------+---------+----------+-------+------+
| 7 | dog > < | 5 | red | 3 |
+------+---------+----------+-------+------+
1 row in set (0.00 sec)
mysql> select * from idx_min where match('test | \\< | a');
+------+---------+----------+-------+------+
| id | doc | group_id | color | size |
+------+---------+----------+-------+------+
| 7 | dog > < | 5 | red | 3 |
+------+---------+----------+-------+------+
1 row in set (0.00 sec)
or
$stmt->bindValue('search', 'test | \\< | a');
in PDO.
There's still a little bug found though which is that if non-spec character is not in charset_table it doesn't generate an error. E.g.
mysql> select * from idx_min where match('test | j | a');
Empty set (0.00 sec)
works fine even though j is not in charset_table. I've filed a bug in our bug tracker https://github.com/manticoresoftware/manticoresearch/issues/156
Thanks again for helping to point this out.
say for exmple you want to do an exact match I like doing my exact matching like this...
...WHERE MATCH(column) AGAINST('happy I am') AND column LIKE '%happy I am%';
that will guarantee I match exactly what I want to match where as if I didn't include the AND LIKE... it would match happy OR I OR am

Receive results of select in shell

Ok, I have such script
#!/bin/bash
keyOrPass=$1
intercom=$2
flat=$3
number=$4
mysql -ulogin -ppass db_name -e "select cli.codeGuestEmail, cli.codePrivateEmail, cliKey.rf_id, cliKey.emailNotification from mbus_clients as cli join mbusClientKeys as cliKey on cliKey.id_client=cli.id WHERE cli.flat=${flat} and cli.domophone=${intercom};";
php -q sendNotifications.php
It works fine, but I should pass some result fields from select into php arguments. Any ideas how to do it?
OUTPUT:
+----------------+------------------+------------+-------------------+
| codeGuestEmail | codePrivateEmail | rf_id | emailNotification |
+----------------+------------------+------------+-------------------+
| 1 | 0 | 2774490192 | 0 |
| 1 | 0 | 2774490193 | 0 |
| 1 | 0 | 2774490194 | 0 |
| 1 | 0 | 2774490195 | 1 |
+----------------+------------------+------------+-------------------+
mysql is capable of generating output formatted differently. With the -B or --batch option, mysql produces the output with TAB as the column separator. The special characters in the fields are escaped (e.g. TAB is output as "\t") so you can use cut to extract fields.
Many times in cases like this it's helpful to use the -N or --skip-column-names option as well, in order to remove column names from the output.

Replacing URL pattern for MySQL

I'm trying to figure out how to use a regex search on a MySQL column to update some data.
The problem is I'm trying to rename part of a URL (i.e a directory).
The table looks something like this (although it's just an example, the actual data is arbitrary):
myTable:
| user_name | URL |
| ------------- |:---------------------------------------------------------:|
| John | http://example.com/path/to/Directory/something/something |
| Jane | http://example.com/path/to/Directory/something/else |
| Jeff | http://example.com/path/to/Directory/something/imgae.jpg |
I need to replace all the URLs that have "path/to/Directory/" to "path/to/anotherDirectory/" while keeping the rest of URL intact.
So the result after the update should look like this:
| user_name | URL |
| ------------- |:----------------------------------------------------------------:|
| John | http://example.com/path/to/anotherDirectory/something/something |
| Jane | http://example.com/path/to/anotherDirectory/something/else |
| Jeff | http://example.com/path/to/anotherDirectory/something/imgae.jpg |
At the moment, the only way I could figure out how to do it is using a combination of regex quires to check for the directory, and then loop over it and change the URL, like this:
$changeArr = $db->query("SELECT URL FROM myTable WHERE URL REGEXP 'path/to/Directory/.+'");
$URLtoChange = "path/to/Directory/";
$replace = "path/to/anotherDirectory/"
foreach ($changeArr as $URL) {
$replace = str_replace($URLtoChange, $replace, $URL);
$db->query("UPDATE myTable SET URL = :newURL WHERE URL = :URL", array("URL"=>$URL,"newURL"=>$replace));
}
This seems to work pretty well, however with such with a big table it can be pretty heavy on performance.
I was wondering if there's a more efficient way to do this? Perhaps with some sort of regex replace in a mySQL query.
Just use the REPLACE() function:
UPDATE myTable
SET URL = REPLACE(url, 'path/to/Directory/', 'path/to/anotherDirectory/')
WHERE URL LIKE '%path/to/Directory/%'

Using strstr() to exclude values in excel while not shifting cells up

I am working in PHP using strstr() to remove values which are extracted from a MYSQL db to be outputted to an excel file-
CODE:
If (!strstr($value, '<script>')){
$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $row, $value);
$row++;
}
This code excludes the columns that contain a <script> tag. However it shifts the contents of the cells up like so:
=====================================
|Question | Answer |
=====+========+===============+=====|
| Male/female | |
|----+--------+---------------+-----|
| | F |
|----+--------+---------------+-----|
Instead I would like it to skip the rows like so:
=====================================
|Question | Answer |
=====+========+===============+=====|
| | |
|----+--------+---------------+-----|
| Male/female | F |
|----+--------+---------------+-----|
Your code is written so that the row is only incremented if your script tag is not found. However, it sounds like you want to unconditionally increment; if that's the case, then move $row++ to outside the if statement, like so:
if (!strstr($value, '<script>')){
$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $row, $value);
}
$row++;
If this isn't what you were looking for, then please provide a sample input that can be matched to the output, as this would make what you need crystal clear.

How to make alignment on console in php

I am trying to run a script through command prompt in PHP and trying to show the result in tabular form. But due to different character length of words I am not able to show the result properly align.
I want result like this
Book ISBN Department
Operating System 101 CS
C 102 CS
java 103 CS
Can anyone please help me to get this output like this in php on console.
Thanks in advance
If you don't want (or not allowed for some reason) to use libraries, you can use standard php printf / sprintf functions.
The problem with them that if you have values with variable and non-limited width, then you will have to decide if long values will be truncated or break table's layout.
First case:
// fixed width
$mask = "|%5.5s |%-30.30s | x |\n";
printf($mask, 'Num', 'Title');
printf($mask, '1', 'A value that fits the cell');
printf($mask, '2', 'A too long value the end of which will be cut off');
The output is
| Num |Title | x |
| 1 |A value that fits the cell | x |
| 2 |A too long value the end of wh | x |
Second case:
// only min-width of cells is set
$mask = "|%5s |%-30s | x |\n";
printf($mask, 'Num', 'Title');
printf($mask, '1', 'A value that fits the cell');
printf($mask, '2', 'A too long value that will brake the table');
And here we get
| Num |Title | x |
| 1 |A value that fits the cell | x |
| 2 |A too long value that will brake the table | x |
If neither of that satisfies your needs and you really need a table with flowing width columns, than you have to calculate maximum width of values in each column. But that is how PEAR::Console_Table exactly works.
You can use PEAR::Console_Table:
Console_Table helps you to display tabular data on a
terminal/shell/console.
Example:
require_once 'Console/Table.php';
$tbl = new Console_Table();
$tbl->setHeaders(array('Language', 'Year'));
$tbl->addRow(array('PHP', 1994));
$tbl->addRow(array('C', 1970));
$tbl->addRow(array('C++', 1983));
echo $tbl->getTable();
Output:
+----------+------+
| Language | Year |
+----------+------+
| PHP | 1994 |
| C | 1970 |
| C++ | 1983 |
+----------+------+
Your best option is to use the Pear Package Console_Table ( http://pear.php.net/package/Console_Table/ ).
To use - on a console you need to install the pear package, running:
pear install Console_Table
this should download the package and install. You can then use a sample script such as:
require_once 'Console/Table.php';
$tbl = new Console_Table();
$tbl->setHeaders(
array('Language', 'Year')
);
$tbl->addRow(array('PHP', 1994));
$tbl->addRow(array('C', 1970));
$tbl->addRow(array('C++', 1983));
echo $tbl->getTable();
You could try the recent simple PHP library ConsoleTable if you don't want to use the standard PHP functions printf/sprintf or the pear package PEAR::Console_Table.
Example:
require_once 'ConsoleTable.php';
$table = new LucidFrame\Console\ConsoleTable();
$table
->addHeader('Language')
->addHeader('Year')
->addRow()
->addColumn('PHP')
->addColumn(1994)
->addRow()
->addColumn('C++')
->addColumn(1983)
->addRow()
->addColumn('C')
->addColumn(1970)
->display()
;
Output:
+----------+------+
| Language | Year |
+----------+------+
| PHP | 1994 |
| C++ | 1983 |
| C | 1970 |
+----------+------+
See more example usages at its github page.
Too old, but i went trough the same now and used str_pad, just set the lenght as the size of your column and thats it
regards.
The CLIFramework table generator helps you get the job done very easily and it supports text alignment, text color, background color, text wrapping, text overflow handling.. etc
Here is the tutorial: https://github.com/c9s/CLIFramework/wiki/Using-Table-Component
Sample code: https://github.com/c9s/CLIFramework/blob/master/example/table.php
use CLIFramework\Component\Table\Table;
$table = new Table;
$table->setHeaders([ 'Published Date', 'Title', 'Description' ]);
$table->addRow(array(
"September 16, 2014",
"Title",
"Description",
29.5
));
$table->addRow(array(
"November 4, 2014",
"Hooked: How to Build Habit-Forming Products",
["Why do some products capture widespread attention whil..."],
99,
));
echo $table->render();
Just in case someone wants to do that in PHP I posted a gist on Github
https://gist.github.com/redestructa/2a7691e7f3ae69ec5161220c99e2d1b3
simply call:
$output = $tablePrinter->printLinesIntoArray($items, ['title', 'chilProp2']);
you may need to adapt the code if you are using a php version older than 7.2
after that call echo or writeLine depending on your environment.

Categories