SlideShare una empresa de Scribd logo
1 de 48
Descargar para leer sin conexión
PHP funcional
além do
array_map
Jean Carlo Machado
Sobre
CompuFácil
⇢ php-src
⇢ git/git
⇢ torvald/linux
⇢ vim/vim
⇢ Doctrine
⇢ Zend Framework
⇢ phpunit
Haskell
1936: Imperativo
jumps: GOTO
1950: Estruturado
subrotinas: while, for, if
GOTO
Programação
Funcional
mudança de estado
Vantagens
Concorrência nativa
Facilita a modularização
Desacelera o apodrecimento
Prática
Estado === Impureza
$inpureIncrement = function (&$count) {
$count++;
};
for ($i = 0; $i < 3; $i++) {
echo "Next:".$inpureIncrement($i);
}
//Next: 0
//Next: 2
//Next: 4
Pureza (relativa)
function pureIncrement($count) {
$myCounter = $count;
$inpureIncrement = function(&$myCounter){
$myCounter++;
};
$inpureIncrement($myCounter);
return $myCounter;
}
//Next: 1
//Next: 2
//Next: 3
Impuros por
natureza
IO
random
Funções de
alta ordem
Retornáveis
$sumPartial = function(int $a) {
return function(int $b) use ($a) {
return $a+b;
}
};
$sumOne = $sumPartial(1);
$sumOne(7);
//8
$sumOne(5);
//6
Repassáveis
$incrementTwo = function ($n, $sumOne) {
return $sumOne($sumOne($n));
};
Fold
Defina o básico
function sum($a, $b) {
return $a + $b;
}
//function product($a, $b);
//function aORb($a, $b);
//function append($a, $b);
//function greater($a, $b);
Componha
$sumList = fold('sum', 0, [1,2,3]);
//6
$multiplyList = fold('product', 1, [2,2,2]);
//8
function fold(
callable $f,
$init,
$list) {
if (empty($list)) {
return $init;
}
return $f(
fold($f, $init, allbutlast($list)),
last($list)
);
};
Map
$double = function($a) {
return $a*2;
}
$map($double, [1, 2, 4]));
//[2,4,8]
$map = function($f, $list) {
$applyAndAppend=function($f,$list,$b){
$list[] = $f($b);
return $list;
};
return fold($applyAndAppend,null)($list);
}
Árvores
$tree = [
1 => [
2,
3 => [
4,
],
]
];
foldTree($sum, $sum, 0, $tree)
//10
Map Tree
$tree = [
3 => [1,4],
1 => [1,5 => [1,2,3]]
];
$result = mapTree($double, $tree);
//[
// 6 => [2,8],
// 2 => [2,10 => [2,4,6]]
//];
PHP functions
⇢ array_map
⇢ array_filter
⇢ array_reduce
⇢ array_sum
⇢ array_unique
g (f input)
⇢ começa f só quando g tenta ler algo
⇢ suspende f
⇢ g roda até precisar ler mais dados
Nth primes
getNthPrimes(10);
//[1,2,3,5,7,11,13,17,19,23]
Nth primes
function primes() {
foreach (finfiniteSequence(1) as $i) {
if (isPrime($i)) {
yield $i;
}
}
}
print_r(ftakefrom(primes(), 10));
//[1,2,3,5,7,11,13,17,19,23]
function isPrime($x) {
$seq = ftakeFrom(
finfiniteSequence(),
$x
);
$seq = fremoveFirst($seq);
$seq = fremoveLast($seq);
$multiple = function($a) use ($x) {
return ($x % $a == 0);
}
return fnoneTrue(
fmap($multiple, $seq)
);
Aplicação parcial
$append3 = function($a, $b, $c) {
return [$a, $b, $c];
};
$append1And2 = fpartial($append3)(1)(2);
$append1And2(5)
//[1,2,5]
$append1And2(9)
//[1,2,9]
function partial(
callable $callable, ...$args){
$arity = (new ReflectionFunction(
$callable
))
->getNumberOfRequiredParameters();
return $args[$arity - 1] ?? false
? $callable(...$args)
: function (...$passedArgs)use($callable,
return partial($callable,
...array_merge($args, $passedArgs)
);
};
Real: get-profile
Requisito v1
curl http://localhost:8000/profile/777
#{"id":777,"name":"Saruman"}
function getProfile(
callable $query,
$userId) {
return $query(
"Select * from User where id = %id ",
$userId
);
}
$realProfile = fpartial
('getProfile')
([new Database, 'query']);
Requisito v2:
cache
curl http://localhost:8000/profile/777
# go to database
#{"id":777,"name":"Saruman"}
curl http://localhost:8000/profile/777
# don't go to database
#{"id":777,"name":"Saruman"}
$memoize = function($func) {
static $results = [];
return function ($a) use (
$func, &$results) {
$key = serialize($a);
if (empty($results[$key])){
$results[$key]=call_user_func(
$func, $a );
}
return $results[$key];
};};
$memoizedProfile = $memoize($realProfile);
Requisito v3: log
request
curl http://localhost:8000/profile/777
#{"id":777,"name":"Saruman"}
# also writes to file
cat /tmp/log
#getProfile called with params s:3:"777";
function fileLogger($str) {
file_put_contents(
'/tmp/log',
"FileLog: ".$str.PHP_EOL,
FILE_APPEND
);
}
function logService(
$logger, $serviceName,
callable $service) {
return function($args) use (
$logger, $serviceName,
$service) {
$logger(
"Service called ". $serviceName.
" with params ".serialize($args));
return call_user_func($service, $args);
};
};
$loggedMemoizedGetProfile =
fpartial('logService')
($logger)
('getProfile')
($memoizedProfile);
Modularização
Mais que módulos
Decompor os problemas em partes menores
Re-compor com avaliação tardia e funções de alta
ordem
Apodrecimento
⇢ Difícil adicionar efeitos sem quebrar as interfaces
⇢ Quão maior a interface mais feio o código
⇢ Interfaces facilmente quebráveis com composicão
⇢ Quebrar encoraja reúso
⇢ Complexidade horizontal ao invés de vertical
Conclusão
Imperativo quando necessário
Funcional quando possível
Para novos tipos
1 - defina as operações fundamentais
2 - junte funções
Seu trabalho não é resolver problemas
Definir problemas de uma forma que
eles se resolvam
Ferramentas
⇢ hlstrojny/functional-php
⇢ functional-php/pattern-matching
⇢ jeanCarloMachado/f
⇢ pimple/pimple
Referências
⇢ Why functional programming matters
⇢ http://archive.li/uTYWZ#selection-407.912-407.919
⇢ https://medium.com/@jugoncalves/functional-programming-
should-be-your-1-priority-for-2015-47dd4641d6b9
⇢ https://blog.inf.ed.ac.uk/sapm/2014/03/06/enemy-of-the-
state-or-why-oop-is-not-suited-to-large-scale-software/
⇢ https://www.youtube.com/watch?v=7Zlp9rKHGD4
⇢ https://www.youtube.com/watch?v=q0HRCEKAcas
Dúvidas?
Github: https://github.com/jeanCarloMachado
Twitter: https://twitter.com/JeanCarloMachad
E-mail: contato@jeancarlomachado.com.br

Más contenido relacionado

La actualidad más candente

20 modules i haven't yet talked about
20 modules i haven't yet talked about20 modules i haven't yet talked about
20 modules i haven't yet talked about
Tatsuhiko Miyagawa
 
Decoupling Objects With Standard Interfaces
Decoupling Objects With Standard InterfacesDecoupling Objects With Standard Interfaces
Decoupling Objects With Standard Interfaces
Thomas Weinert
 

La actualidad más candente (20)

20 modules i haven't yet talked about
20 modules i haven't yet talked about20 modules i haven't yet talked about
20 modules i haven't yet talked about
 
8.1
8.18.1
8.1
 
Parsing JSON with a single regex
Parsing JSON with a single regexParsing JSON with a single regex
Parsing JSON with a single regex
 
How to stand on the shoulders of giants
How to stand on the shoulders of giantsHow to stand on the shoulders of giants
How to stand on the shoulders of giants
 
C++ programs
C++ programsC++ programs
C++ programs
 
PHP pod mikroskopom
PHP pod mikroskopomPHP pod mikroskopom
PHP pod mikroskopom
 
ZeroMQ Is The Answer: DPC 11 Version
ZeroMQ Is The Answer: DPC 11 VersionZeroMQ Is The Answer: DPC 11 Version
ZeroMQ Is The Answer: DPC 11 Version
 
C program to implement linked list using array abstract data type
C program to implement linked list using array abstract data typeC program to implement linked list using array abstract data type
C program to implement linked list using array abstract data type
 
Pratik Bakane C++
Pratik Bakane C++Pratik Bakane C++
Pratik Bakane C++
 
Pratik Bakane C++
Pratik Bakane C++Pratik Bakane C++
Pratik Bakane C++
 
Decoupling Objects With Standard Interfaces
Decoupling Objects With Standard InterfacesDecoupling Objects With Standard Interfaces
Decoupling Objects With Standard Interfaces
 
The Magic Of Tie
The Magic Of TieThe Magic Of Tie
The Magic Of Tie
 
The Truth About Lambdas in PHP
The Truth About Lambdas in PHPThe Truth About Lambdas in PHP
The Truth About Lambdas in PHP
 
Final ds record
Final ds recordFinal ds record
Final ds record
 
Pratik Bakane C++
Pratik Bakane C++Pratik Bakane C++
Pratik Bakane C++
 
Pratik Bakane C++
Pratik Bakane C++Pratik Bakane C++
Pratik Bakane C++
 
Avl tree
Avl treeAvl tree
Avl tree
 
Pratik Bakane C++
Pratik Bakane C++Pratik Bakane C++
Pratik Bakane C++
 
2016 gunma.web games-and-asm.js
2016 gunma.web games-and-asm.js2016 gunma.web games-and-asm.js
2016 gunma.web games-and-asm.js
 
Circular queue
Circular queueCircular queue
Circular queue
 

Similar a Functional php

Object Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPObject Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOP
Wildan Maulana
 
JavaScript for PHP developers
JavaScript for PHP developersJavaScript for PHP developers
JavaScript for PHP developers
Stoyan Stefanov
 
jQuery: out with the old, in with the new
jQuery: out with the old, in with the newjQuery: out with the old, in with the new
jQuery: out with the old, in with the new
Remy Sharp
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Development
jsmith92
 
Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02
Seri Moth
 

Similar a Functional php (20)

PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolve
 
Functional programming with php7
Functional programming with php7Functional programming with php7
Functional programming with php7
 
Functional Programming in PHP
Functional Programming in PHPFunctional Programming in PHP
Functional Programming in PHP
 
Adding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy ApplicationsAdding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy Applications
 
エラー時にログに出力する情報と画面に表示する情報を分ける #LaravelTokyo
エラー時にログに出力する情報と画面に表示する情報を分ける #LaravelTokyoエラー時にログに出力する情報と画面に表示する情報を分ける #LaravelTokyo
エラー時にログに出力する情報と画面に表示する情報を分ける #LaravelTokyo
 
Object Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPObject Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOP
 
Why async and functional programming in PHP7 suck and how to get overr it?
Why async and functional programming in PHP7 suck and how to get overr it?Why async and functional programming in PHP7 suck and how to get overr it?
Why async and functional programming in PHP7 suck and how to get overr it?
 
Generating Power with Yield
Generating Power with YieldGenerating Power with Yield
Generating Power with Yield
 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4
 
Functional Structures in PHP
Functional Structures in PHPFunctional Structures in PHP
Functional Structures in PHP
 
JavaScript for PHP developers
JavaScript for PHP developersJavaScript for PHP developers
JavaScript for PHP developers
 
jQuery: out with the old, in with the new
jQuery: out with the old, in with the newjQuery: out with the old, in with the new
jQuery: out with the old, in with the new
 
Elements of Functional Programming in PHP
Elements of Functional Programming in PHPElements of Functional Programming in PHP
Elements of Functional Programming in PHP
 
Tidy Up Your Code
Tidy Up Your CodeTidy Up Your Code
Tidy Up Your Code
 
Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
 
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsA Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP Generators
 
The promise of asynchronous php
The promise of asynchronous phpThe promise of asynchronous php
The promise of asynchronous php
 
Durian: a PHP 5.5 microframework with generator-style middleware
Durian: a PHP 5.5 microframework with generator-style middlewareDurian: a PHP 5.5 microframework with generator-style middleware
Durian: a PHP 5.5 microframework with generator-style middleware
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Development
 
Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02
 

Más de Jean Carlo Machado (10)

Python clean code for data producs
Python clean code for data producsPython clean code for data producs
Python clean code for data producs
 
Domain Driven Design Made Functional with Python
Domain Driven Design Made Functional with Python Domain Driven Design Made Functional with Python
Domain Driven Design Made Functional with Python
 
Search microservice
Search microserviceSearch microservice
Search microservice
 
Why functional programming matters
Why functional programming mattersWhy functional programming matters
Why functional programming matters
 
Clean code v3
Clean code v3Clean code v3
Clean code v3
 
Clean Code V2
Clean Code V2Clean Code V2
Clean Code V2
 
Review articles bio inspired algorithms
Review articles bio inspired algorithmsReview articles bio inspired algorithms
Review articles bio inspired algorithms
 
Introduction to Rust
Introduction to RustIntroduction to Rust
Introduction to Rust
 
Limitações do HTML no Desenvolvimento de Jogos Multiplataforma
Limitações do HTML no Desenvolvimento de Jogos MultiplataformaLimitações do HTML no Desenvolvimento de Jogos Multiplataforma
Limitações do HTML no Desenvolvimento de Jogos Multiplataforma
 
Clean code
Clean codeClean code
Clean code
 

Último

+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
VictorSzoltysek
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
masabamasaba
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
shinachiaurasa2
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
masabamasaba
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
masabamasaba
 

Último (20)

Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
 
%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 

Functional php